龙空技术网

深入了解并发编程的核心概念:进程与线程

Java济公 166

前言:

今天大家对“线程拥有的必不可少的资源”可能比较珍视,小伙伴们都需要分析一些“线程拥有的必不可少的资源”的相关资讯。那么小编在网络上网罗了一些有关“线程拥有的必不可少的资源””的相关文章,希望小伙伴们能喜欢,朋友们一起来了解一下吧!

1、进程和线程:进程

进程概念:

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。进程是一个动态的概念,它可以申请和拥有系统资源,是一个活动的实体。

进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。第二,进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态之间的转换等功能。

进程基本状态及转换:

进程状态

进程控制结构:

进程控制结构概念:

进程控制结构,也称为进程控制块(PCB),是系统为了管理进程而设置的一个专门的数据结构。系统用它来记录进程的外部特征,描述进程的运动变化过程。PCB是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,在创建进程时建立PCB,伴随进程运行的全过程,直到进程撤消而撤消。

PCB中通常包含以下信息:

进程标识符:用于唯一标识一个进程。进程状态:描述进程当前的状态,如就绪状态、阻塞状态等。处理器状态:保存了处理器运行时的一些信息,如程序计数器、堆栈指针等。内存指针:指向进程的代码段、数据段和堆栈段的指针。资源清单:列出了进程所需的资源,如文件、设备等。信号掩码:用于屏蔽某些信号,以避免对进程的干扰。优先级:用于确定进程的调度优先级。链接指针:用于将相关进程链接起来,以便于管理和调度。

PCB是系统感知进程存在的唯一标志,通过PCB可以对进程进行控制和管理。在不同的操作系统中,PCB的具体实现可能会有所不同,但它们的基本功能和结构是相似的。

链表组织:

进程通过链表的方式组织在一起,就具有相同的状态的进程组织在一起,组成各种不同的队列,比如就绪队列,运行队列等;同组状态放在同一个索引表中,不同状态放在不同的索引表中

链表组织

进程控制过程:

进程的创建:当出现创建进程的事件时,如用户登录、作业调度、提供服务或应用请求等,操作系统会创建一个新的进程。创建过程包括申请空白PCB,为新进程分配所需的资源,初始化进程控制块,并将新进程插入到就绪队列中。进程的终止:当进程正常结束、异常结束或因外界干预而结束时,操作系统会调用内核终止原语来执行终止操作。这个过程包括根据进程标识符检索出该进程的PCB,读取其状态,归还其占用的所有资源给父进程或系统,并将该PCB从所在队列中移出。进程的阻塞:当进程在执行过程中遇到某种等待事件时,如等待I/O操作完成、等待信号或等待其他资源,操作系统会将该进程阻塞,并将其从就绪队列中移出,放入相应的阻塞队列中。当等待事件完成后,操作系统会将该进程唤醒,将其从阻塞队列中移出,重新放入就绪队列中等待调度。

进程上下文切换:

进程上下文切换是操作系统实现并发和多任务处理的重要手段之一,它可以提高系统的执行效率和响应能力。但是上下文切换也存在一定的开销,频繁的上下文切换会对系统性能产生影响。因此,操作系统需要根据系统的负载情况和资源利用率进行合理的调度和管理,以实现高效的系统运行。

上下文切换需要保存和恢复CPU寄存器和程序计数器的状态,通常由操作系统内核在CPU上运行来完成。上下文切换是计算密集型的操作,需要消耗一定的时间和计算资源。

上下文切换的原因有多种,例如当前正在执行的进程完成,系统的CPU正常调度下一个任务;当前正在执行的进程遇到I/O等阻塞操作,调度器挂起此任务,继续调度下一个任务;多个任务并发抢占锁资源,当前任务没有抢到锁资源,被调度器挂起,继续调度下一个任务;用户的代码挂起当前任务,比如线程执行yield()方法,让出CPU;硬件中断等。

进程上下文切换

2、进程和线程:线程

了解了进程概念后,看看为什么要引入线程?

1、根据一个业务功能来解释,假如你要实现从文件读取数据,然后插入三个不同的mysql表中,单进程伪代码实现如下

//单进程实现main(){    //读取A表数据插入A表		ReadAFile(from AFile);  	insertATable();      //读取B表数据插入B表  	ReadBFile(from BFile);	  insertBTable();      //读取C表数据插入C表    ReadCFile(from CFile);	  insertCTable();}

问题:

1、B表的操作只能等A表完成操作,C表的操作只能等B表完成操作;2、当资源有限时,比如CPU能力不强,前一步动作一直卡住等待,3、各个函数之间不是并发执行,影响资源利用率。

2、多进程伪代码实现如下:

//进程Amain(){    //读取A表数据插入A表		ReadAFile(from AFile);  	insertATable();}//进程Bmain(){  	ReadBFile(from BFile);	  insertBTable();}//进程Cmain(){    //读取C表数据插入C表    ReadCFile(from CFile);	  insertCTable();}

问题:

1、进程A、进程B、进程C都是互相独立2、如何通信,资源如何共享3、进程创建开销大、如何创建进程时分配资源,创建PCB,回收进程时,回收资源,撤销PCB,进程上下文切换时,保存当前状态的信息

3、为什么要引入线程?

为了解决进程碰到问题,解决可以并发运行、解决相同地址空间可以共享,解决开销问题,引入Thread对象。

4、线程

概念:线程是进程中一条执行流程,同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程都有独立一套的寄存器和栈,这样可以确保线程的控制流是相对独立的

多线程

线程与进程比较:

定义:进程是资源 (包括内存、打开的文件等) 分配的单位,线程是 CPU 调度的单位;进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系,线程能减少并发执行的时间和空间开销:独立性:一个线程只可以属于一个进程,但一个进程能包含多个线程。开销:由于同一进程内的多个线程共享进程的地址空间,因此,这些线程之间的同步与通信非常容易实现,甚至无需操作系统的干预。线程的开销或代价比进程的小。并发性:在引入线程的操作系统中,线程是独立调度的基本单位,进程是资源拥有的基本单位。在同一进程中,线程的切换不会引起进程切换。在不同进程中进行线程切换,如从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。不论是传统操作系统还是设有线程的操作系统,进程都是拥有资源的基本单位,而线程不拥有系统资源(也有一点必不可少的资源),但线程可以访问其隶属进程的系统资源。

线程上下文切换:

线程是调度的基本单位,而进程则是资源拥有的基本单位,所以,所谓操作系统的任务调度,实际上的调度对象是线程,而进程只是给线程提供了内存、全局变量等资源;当进程只有一个线程时,可以认为进程就等于线程,当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时是不需要修改的;线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存的。

当A线程和B线程属于两个不同的进程,切换过程跟进程切换一样:

当A线程和B线程属于同一个进程,切换过程中共享的虚拟内存不需切换,只需切换私有的寄存器、私有的不共享数据:

线程的实现:

内核线程:使用内核线程实现(1[进程]:1[线程]),内核直接管理线程,每个线程都需要内核的支持,因此切换时需要系统调用,开销较大。

用户线程:使用用户线程实现(1[进程]:N[线程]),用户线程不需要内核支持,切换时无需系统调用,开销较小。但需要自己处理同步和通信问题。

轻量级进程:使用用户线程加轻量级进程实现(N[进程]:M[线程]),这种方式结合了上述两种方式的优点,可以快速且低消耗地进行线程切换。

敬请期待后续篇章线程生命周期、线程通信、Java内存模型、并发基础、并发集合、并发工具、阻塞队列、线程池

标签: #线程拥有的必不可少的资源 #线程是资源调度的基本单位 #线程是资源调度的基本单位吗为什么