进程与线程
为了有效地管理CPU,操作系统引入了线程的概念,即以进程为基本单位来实现CPU的分配与执行。随着并行处理技术的发展,为了进一步提高系统的并行性,实现进程内部的并发执行,操作系统又引入了线程的概念。这样,CPU的管理最终归结于对进程和线程的管理。
一、进程
程序是一个在时间上严格按照先后次序擦欧洲哦的实现算法功能的指令序列。
1.1 程序的顺序执行和并发执行
1.1 顺序执行
一个具有独立功能的程序独占CPU运行,直到获得最终结果的过程。
- 顺序性。 每个操作都必须在前一个操作结束后才能开始
- 封闭性。 程序一旦开始运行,其运行结果不会受到外界因素的影响
- 可再现性。 程序运行结果仅由初始结果和程序本身的操作决定
1.1.2 并发执行
在计算机引入通道和中断机制后,就使得CPU和外部设备之间,以及外部设备与外部设备之间可以并行操作,使得多道程序设计成为可能。
在同一时刻,有的程序占用CPU运行,有的程序通过外部设备传递数据。从宏观上看是多个设备同时运行,从微观上来看它们是在交替运行。
因此,程序并发执行环境下的计算机资源,已不再被某一个用户程序所独占,而是由多个并发执行的程序所共享。虽然提高了资源的利用率,但在另外一方面却引发了多个并发程序对资源的竞争导致了程序执行环境与运行速度的改变,从而可能产生程序运行结果不唯一的情况。
- 间断性
- 无封闭性
- 不可再现性
1.2 进程的定义
程序的一个动态执行过程
结构:
进程实体=程序段+相关数据段+PCB(进程控制块)
1.4 进程的特点
- 动态性。 进程具有生命期,具有“创建-运行-消亡”这样一个过程
- 并发性。 多个进程能够在一段时间内并发执行
- 独立性。 每个进程都是一个独立运行的基本单位,也是系统进行资源分配和调度的基本单位
- 异步性。 任何时刻只能有一个进程占用CPU,具有“执行-暂停-执行”这种间断性规律
- 结构性。 由程序段、相关数据段、PCB三部分组成
1.5 进程和程序的区别
程序像是一个乐谱,任何时候都可以翻阅它,但乐谱本身是静态的。
进程则可以看做是乐谱的一次演奏,具有生命周期,并随着时间的流逝,演奏的音乐将不复存在,即使是重现演奏这个乐谱,也不是刚刚逝去的那段音乐。
同一程序的不同进程,则像是同卵双胞胎的不同人生。
程序和进程并无一一对应关系。同一程序可以产生多个进程,一个进程也可包含多个程序。
1.6 进程的状态及转换
-
新建
当需要创建一个新进程时,系统为该进程分配一个进程控制块PCB,并为该进程分配内存空间,且装入该进程对应的程序和有关数据。 -
就绪
进程得到除了CPU之外的所需资源,一旦得到CPU资源既可以立即投入运行。 -
运行
进程获得了CUP和其他所需要的资源,目前正在CPU上运行 -
阻塞
进程 运行 过程中发生了某种等待事件(比如发生了I/O操作)而暂时不能运行的状态。即使把CPU资源分配给它也不能够运行。 -
结束
系统逐步释放为为其分配的资源,最后释放其PCB.
核心的三状态就比如一个游乐场,一群小朋友进入游乐场排序玩一个滑梯
- 排队的小朋友就处于就绪转态
- 玩滑梯的那一个小朋友就处于运行状态
- 每个小朋友只能玩5分钟,时间到了就得重新排序
- 如果小朋友在玩滑梯的过程中需要上厕所,那么上厕所的过程就是阻塞状态,上厕所结束后则需要重新排队(就绪)
上面的5状态进程模型中,新创建的进程一旦被系统接纳都一直存在于内存中,直到被终止。在这种情况下,系统内存资源会变得越来越紧张,此外由于CPU速度远超于I/O等操作速度,内存中就会存在大多数进程等待I/O操作而CPU空闲的现象。为此可以采用交换技术,将内存中暂时不能运行的某些进程挂起,释放所占用的内存资源,以便于重新接纳一个新进程或外存上已具备运行条件的进程进入内存就绪队列。进程挂起即将内存中的进程暂时移出到外存(如磁盘)中的过程。
现代操作系统只是将进程的某些页放到外存上去
二、进程同步与通信
2.1 进程的同步与互斥
2.1.1 进程同步
某些进程之间在逻辑上的相互制约关系,即若干进程为了完成某一个共同任务和相互合作。
2.1.2 进程互斥
某一资源同一时间只允许一个进程对其访问,这种访问具有唯一性和排他性。
2.2 临界资源和临界区
系统中同时存在着许多进程,它们共享着各种资源。然而许多资源在某一时刻只能允许一个进程使用,如打印机,磁带机等硬件设备,软件中的变量、队列等数据结构。如果多个进程同时使用这类资源就会造成混乱。因此必须保护这些资源,避免两个或多个进程同时访问这些资源。
把同一时刻只允许一个进程使用的资源成为临界资源。
对临界资源的访问必须互斥进行,即各个进程对同一临界资源进行先从操作的程序段也应互斥进行,只有这样才能保证对临界资源的互斥访问。把进程中访问临界资源的代码称为临界区。
对于临界资源的访问必须互斥进行,所以进程在进入临界区时首先判断是否有其他进程在使用此临界资源,如果有,则该进程必须等待;如果没有,则该进程才能进入临界区执行临界区代码,同时还要关闭临界区以防止其他进程进入。当进程使用完临界资源时,要开放临界区以便其他进程进入。
2.3 实现进程互斥的硬件方法
2.3.1 开关中断指令
又称硬件锁,进程在进入临界区之前,先执行“关中断”指令来屏蔽掉所有中断,进程完成所有临界区的任务后,再执行“开中断”指令将中断打开。
开关中断时间过长会导致系统效率降低。
2.3.2 测试与设置指令
为每一个临界资源设置一个整型变量s,若s为0,则表示没有进程访问该临界资源,若s为1则表示该临界资源已经被某个进程占用。
利用TS指令可以实现临界区的开锁和关锁原语操作,进入临界区之前先使用TS指令测试s,若s为0则表明没有进程使用临界资源,于是本进程进入临界区,否则必须循环测试直至s的值为0。
原语:一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断。(原子操作)
2.3.3 交换指令
若要使用交换指令来实现进程互斥,则需要为每个临界资源设置一个整型变量s,若s为0,则表示没有进程访问该临界资源,若s为1则表示该临界资源已经被某个进程占用。此外,还有设置一个整型局部变量key,只有当s为0且key为1时,进程才能进入临界区,进入临界区后,s的值为1且key的值为0。
TS和SWAP指令都能方便地实现进程互斥,但都存在过多循环测试s的值而引起的系统资源消耗问题。
2.4 实现进程互斥的软件方法
2.4.1 两标志进程互斥算法
不能很好解决两个进程同时到达的问题
2.4.2 三标志进程互斥算法
扩展性较差,进程一多久复杂了,效率变低
2.5 信号量机制
在操作系统中,信号量代表了一类物理资源,它是相应物理资源的抽象。具体实现时,信号量被定义为具有某种类型的变量,通常为整型或者其他结构体类型。
value变量:
value的初值是一个非负整数,代表着系统中某类资源的数量,随着该资源的不断被分配,value的值也随之发生变化,会出现以下三种情况:
- value>0,代表该类资源当前的可用数量
- value=0,表示该资源为空
- value<0,其绝对值代表因等待该资源而阻塞的进程数量
P操作(发信号):
- 执行一此P操作就相当于申请一个资源S
- 若S>0,则意味着系统中有可用资源S,并将其分配,且将S的资源可用数量value减1
- 若S<=0,表示当前系统已无资源S可用,立即将当前运行进程阻塞起来,并插入到S.L的进程阻塞队列中去
V操作(等待):
- 执行一次V操作相当于释放一个资源S,将资源S的value值加1
- 若S.value加1后其值仍小于等于0,则表明仍有处于阻塞状态的进程在等待资源S,于是将S.L所指进程阻塞队列中的第一个阻塞进程唤醒并将刚刚回收的资源S分配给它。
P、V信号量解决了进程主动进行循环测试消耗系统资源的问题。因为这种协调的本质是当出现资源竞争的冲突时,就将原来并发执行的多个进程在P、V操作的协调下变为依次顺序执行,当资源冲突结束后又恢复为并发执行。
三、线程
进程就如我们在一台旧电视上看节目,如果两个频道正在直播不同的精彩节目,我们只能在这两个频道之间来回切换选择观看的内容(相当于进程的切换)。这就是进程的缺点,它在一个时间段内只能做一件事情,如果想要同时做两件或者多件事情,进程就不够用了。此外,如果进程在执行过程中因等待输入输入数据而阻塞,且这时进程还有一些不依赖于输入的其他工作可以做,但由于进程的阻塞而无法进行。
线程就是为了解决上述两个缺陷而解决的,例如新电视可以将两个频道或多个频道同时显示在同一块屏幕上(分屏),这就是线程的方式。例如使用WPS时,实际上是打开了多线程,一个线程负责显示,一个线程负责输入,一个线程负责定时存盘...... 这些线程一起运转,使我们觉得输入和显示同时发生,而不是键入一些文字,等待一会儿再显示到屏幕上。
多线程,在一个口罩工厂中建立多个生产线生产口罩 (一个进程内的多个线程)
并行:同一时刻,多个执行流都拥有一个CPU同时在计算
并发:多个执行流,每个执行流独占CPU一会儿进行计算,按照时间片轮转法分配运行时间
3.1 线程的引入
在操作系统中引入进程后,使得原来不能并发执行的程序变成能够并发执行的进程,从而改善了资源的利用率和系统吞吐量。此时,进程既是资源分配的基本单位,也是独立调度、独立运行的基本单位。
然而,正是由于进程扮演了这两种角色,导致了进程的并发执行产生了很大的时空开销,因为他要完成如下操作:
- 创建进程
- 进程切换
- 撤销进程
上述操作占用不少的CPU资源(尤其是进程切换),为此有一个想法是将进程承担的两个角色分开。
此外,多CPU的计算机系统的出现,对于原有的进程执行方式增加CPU并不能提高一个进程的执行效率。 将一个进程分解为多个线程,这样就可以让多个线程同时运行在不同的CPU上。 此时,线程是CPU调度和执行的最小单元
3.2 线程的定义
- 进程内的一个执行单元
- 进程内的一个可独立调度的实体
- 进程内的一个相对独立的控制流序列
- 执行的上下文
属性:
- 线程属于轻型实体,基本不拥有系统资源
- 线程是独立调度和分配的基本单位,也是能够独立运行的基本单位
- 同一个进程的所有线程共享该进程的所拥有的全部资源
- 线程的并发执行程度高,不但同一进程的多个线程可以并发执行,甚至属于不同进程的多个线程也可以并发执行
与进程类似,线程也有生命周期,也存在 执行、就绪和阻塞这三种基本状态,这是因为线程完全继承了进程的运行属性,因此线程的三种状态含义和转换关系与进程相同。由于线程不是资源的拥有单位,因此挂起状态对单个线程没有意义。
在多线程操作系统中,为了使并发的多个线程能够有条不紊地运行,操作系统必须提供用于线程间互斥和同步的机制:
- 互斥锁,每次只允许一个线程来执行特定的代码或访问特定的数据。
- 读写锁,对受保护的共享资源进行并发读取和独占写入。
- 条件变量,一直阻塞线程,直到特定的条件为真。
- 奇数信号量,用来协调对资源的访问,达到指定的计数时信号将阻塞。
3.3 线程与进程
线程有由于有很多进程的特性,因此有人将它称为轻量级进程,而将传统进程称为重量级进程。
差异:
- 新建、切换和撤销一个线程所花费的时空消耗远小于新建、切换和撤销一个进程的时空开销
- 进程是资源分配的最小单元,而线程不是,同一进程的多个线程可以共享资源
参考