Computer Operation System
安徽师范大学——计算机与信息学院———— 作者(授课教师): 周文
在早期未配置OS的系统和单道批处理系统中,程序的执行方式是顺序执行
为了能更好地描述程序的顺序和并发执行情况,我们先介绍用于描述程序执行先后顺序的前趋图
。
Precedence Graph
),是指一个有向无循环图,可记为DAG
(Directed Acyclic Graph
),它用于描述进程之间执行的先后顺序
。Partial Order
)或前趋关系(Precedence Relation
)进程(或程序)之间的前趋关系可用“→
”来表示,
如果进程Pi和Pj存在着前趋关系,可表示为(Pi,Pj)∈→
,也可写成Pi→Pj
,表示在Pj
开始执行之前Pi
必须完成。此时称Pi
是Pj
的直接前趋,而称Pj是Pi的直接后继。
在前趋图中,把没有前趋的结点称为初始结点(Initial Node),把没有后继的结点称为终止结点(Final Node)。此外,每个结点还具有一个重量(Weight),用于表示该结点所含有的程序量或程序的执行 时间。
在图2-1(a)所示的前趋图中,存在着如下前趋关系:
或表示为:
注意:前趋图中是不允许有循环的,否则必然会产生不可能实现的前趋关系。
如图2-1(b)所示的前趋关系中就存在着循环。
显然,这种关系是不可能实现的。
程序的顺序执行
用结点(Node)代表各程序段的操作(在图2-1中用圆圈表示),其中I代表输入操作
,C代表计算操作
,P为打印操作
,用箭头指示操作的先后次序。
这样,上述的三个程序段间就存在着这样的前趋关系:Ii→Ci→Pi
,其执行的顺序可用前趋图2-2(a)描述。
其中,语句S2必须在语句S1后(即a被赋值)才能执行,语句S3也只能在b被赋值后才能执行。
因此,三条语句存在着这样的前趋关系:S1→S2→S3
,应按前趋图2-2(b)所示的顺序执行。
程序顺序执行时的特征
由上所述可以得知,在程序顺序执行时,具有这样三个特征
:
① 顺序性
:指处理机严格地按照程序所规定的顺序执行,即每一操作必须在下一个操作开始之前结束;
② 封闭性
:指程序在封闭的环境下运行,即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它,程序一旦开始执行,其执行结果不受外界因素影响;
③ 可再现性
:指只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都可获得相同的结果。程序顺序执行时的这种特性,为程序员检测和校正程序的错误带来了很大的方便
程序的并发执行
通过一个常见的例子来说明程序的顺序执行和并发执行。
在图2-2中的输入程序、计算程序和打印程序三者之间,存在着Ii→Ci→Pi
这样的前趋关系,以至对一个作业的输入、计算和打印三个程序段必须顺序执行。
但若是对一批作业进行处理时,每道作业的输入、计算和打印程序段的执行情况如图2-3所示。
由图2-3可以看出,存在前趋关系Ii→Ci,Ii→Ii+1,Ci→Pi,Ci→Ci+1,Pi→Pi+1
,而Ii+1
和Ci
及Pi-1
是重叠的,即在Pi-1
和Ci
以及Ii+1
之间,不存在前趋关系,可以并发执行。
对于具有下述四条语句的程序段:
可画出图2-4所示的前趋关系。可以看出:S3
必须在a和b被赋值后方能执行;S4
必须在S3
之后执行;但S1和S2则可以并发执行,因为它们彼此互不依赖。
程序并发执行时的特征
但由于它们共享系统资源,以及它们为完成同一项任务而相互合作,致使在这些并发执行的程序之间必将形成相互制约的关系,由此会给程序并发执行带来新的特征。
(1) 间断性
。
(2) 失去封闭性
。
(3) 不可再现性
。
进程的定义
进程
”的概念。对于进程的定义,从不同的角度可以有不同的定义,其中较典型的定义有:
(1) 进程是程序的一次执行。
(2) 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
(3) 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
进程和程序是两个截然不同的概念,除了进程具有程序所没有的PCB结构外,还具有下面一些特征:
(1) 动态性。
(2) 并发性。
(3) 独立性。
(4) 异步性。
1.进程的三种基本状态
由于多个进程在并发执行时共享系统资源,致使它们在运行过程中呈现间断性的运行规律,所以进程在其生命周期内可能具有多种状态。
一般而言,每一个进程至少应处于以下三种基本状态之一:
(1) 就绪(Ready)状态
。
(2) 执行(Running)状态
。
(3) 阻塞(Block)状态
。
三种基本状态的转换
就绪态转变为执行态
;图2-5示出了进程的三种基本状态,以及各状态之间的转换关系。
挂起操作的引入
引入挂起操作的原因,是基于系统和用户的如下需要:
(1) 终端用户的需要。
(2) 父进程请求。
(3) 负荷调节的需要。
(4) 操作系统的需要。
引入挂起原语操作后三个进程状态的转换
在引入挂起原语Suspend
和激活原语Active
后,在它们的作用下,进程将可能发生以下几种状态的转换:
(1) 活动就绪→静止就绪。
(2) 活动阻塞→静止阻塞。
(3) 静止就绪→活动就绪。
(4) 静止阻塞→活动阻塞。
引入挂起操作后五个进程状态的转换
如图2-8示出了增加了创建状态和终止状态后具有挂起状态的进程状态及转换图。
如图2-8所示,引进创建和终止状态后,在进程状态转换时,与图2-7所示的进程五状态转换相比较,要增加考虑下面的几种情况:
(1) NULL→创建:
(2) 创建→活动就绪:
(3) 创建→静止就绪:
(4) 执行→终止:
操作系统中用于管理控制的数据结构
在计算机系统中,对于每个资源和每个进程都设置了一个数据结构,用于表征其实体,我们称之为资源信息表或进程信息表。
通过这些指针,可以将同类资源或进程的信息表,或者同一进程所占用的资源信息表分类链接成不同的队列,便于操作系统进行查找。
内存表
、设备表
、文件表
和用于进程管理的进程表
,通常进程表又被称为进程控制块PCB
。 进程控制块PCB的作用
(1) 作为独立运行基本单位的标志。
(2) 能实现间断性运行方式。
(3) 提供进程管理所需要的信息。
(4) 提供进程调度所需要的信息。
(5) 实现与其它进程的同步与通信。
进程控制块中的信息
在进程控制块中,主要包括下述四个方面的信息。
1) 进程标识符
进程标识符用于唯一地标识一个进程。一个进程通常有两种标识符:
(1) 外部标识符。
(2) 内部标识符。
2) 处理机状态
3) 进程调度信息
这些信息包括:
① 进程状态,指明进程的当前状态,它是作为进程调度和对换时的依据;
② 进程优先级,是用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机;
③ 进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待CPU的时间总和、进程已执行的时间总和等;
④ 事件,是指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
4) 进程控制信息
指用于进程控制所必须的信息,它包括:
① 程序和数据的地址,进程实体中的程序和数据的内存或外存地(首)址,以便再调度到该进程执行时,能从PCB中找到其程序和数据;
② 进程同步和通信机制,是实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在PCB中;
③ 资源清单,在该清单中列出了进程在运行期间所需的全部资源(除CPU以外),另外还有一张已分配到该进程的资源的清单
④ 链接指针,它给出了本进程(PCB)所在队列中的下一个进程的PCB的首地址。
在一个系统中,通常可拥有数十个、数百个乃至数千个PCB。为了能对它们加以有效的管理,应该用适当的方式将这些PCB组织起来。目前常用的组织方式有以下三种。
(1) 线性方式
,即将系统中所有的PCB都组织在一张线性表中,将该表的首址存放在内存的一个专用区域中。该方式实现简单、开销小,但每次查找时都需要扫描整张表,因此适合进程数目不多的系统。图2-10示出了线性表的PCB组织方式。
(2) 链接方式
,即把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列。这样,可以形成就绪 队列、若干个阻塞队列和空白队列等。
对就绪队列而言,往往按进程的优先级将PCB从高到低进行排列,将优先级高的进程PCB排在队列的前面。同样,也可把处于阻塞状态进程的PCB根据其阻塞原因的不同,排成多个阻塞队列,如等待I/O操作完成的队列和等待分配内存的队列等。图2-11示出了一种链接队列的组织方式。
(3) 索引方式
,即系统根据所有进程状态的不同,建立几张索引表,例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。
在每个索引表的表目中,记录具有相应状态的某个PCB在PCB表中的地址。图2-12示出了索引方式的PCB组织。
进程控制是进程管理中最基本的功能
当一个正在执行的进程因等待某事件而暂时不能继续执行时,将其转变为阻塞状态,而在该进程所期待的事件出现后,又将该进程转换为就绪状态等。进程控制一般是由OS的内核中的原语来实现的。
1.支撑功能 (1) 中断处理 (2) 时钟管理 (3) 原语操作
2.资源管理功能 (1) 进程管理 (2) 存储器管理 (3) 设备管理
进程的层次结构
在OS中,允许一个进程创建另一个进程,把创建进程的进程称为父进程,而把被创建的进程称为子进程。
子进程可继续创建更多的孙进程,由此便形成了一个进程的层次结构。如在UNIX中,进程与其子孙进程共同组成一个进程家族(组)。
进程图
为了形象地描述一个进程的家族关系而引入了进程图(Process Graph)。所谓进程图就是用于描述进程间关系的一棵有向树,如图2-13所示。
引起创建进程的事件
为使程序之间能并发运行,应先为它们分别创建进程。导致一个进程去创建另一个进程的典型事件有四类:
(1) 用户登录。
(2) 作业调度。
(3) 提供服务。
(4) 应用请求。
进程的创建(Creation of Process
)
在系统中每当出现了创建新进程的请求后,OS便调用进程创建原语Create按下述步骤创建一个新进程:
(1) 申请空白PCB,为新进程申请获得唯一的数字标识符,并从PCB集合中索取一个空白PCB。
(2) 为新进程分配其运行所需的资源,包括各种物理和逻辑资源,如内存、文件、I/O设备和CPU时间等。
(3) 初始化进程控制块(PCB)。
(4) 如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列。
引起进程终止(Termination of Process)的事件
(1) 正常结束
(2) 异常结束
(3) 外界干预
进程的终止过程
如果系统中发生了要求终止进程的某事件,OS便调用进程终止原语,按下述过程去终止指定的进程:
(1) 根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态;
(2) 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度;
(3) 若该进程还有子孙进程,还应将其所有子孙进程也都予以终止,以防它们成为不可控的进程;
(4) 将被终止进程所拥有的全部资源或者归还给其父进程,或者归还给系统;
(5) 将被终止进程(PCB)从所在队列(或链表)中移出,等待其它程序来搜集信息。
引起进程阻塞和唤醒的事件
有下述几类事件会引起进程阻塞或被唤醒:
(1) 向系统请求共享资源失败。
(2) 等待某种操作的完成。
(3) 新数据尚未到达。
(4) 等待新任务的到达。
进程阻塞过程 正在执行的进程,如果发生了上述某事件,进程便通过调用阻塞原语block将自己阻塞。可见,阻塞是进程自身的一种主动行为。
进程唤醒过程
当被阻塞进程所期待的事件发生时,比如它所启动的I/O操作已完成,或其所期待的数据已经到达,则由有关进程(比如提供数据的进程)调用唤醒原语wakeup,将等待该事件的进程唤醒。
wakeup
执行的过程是:
PCB
插入到就绪队列中。两种形式的制约关系
1) 间接相互制约关系
2) 直接相互制约关系
临界资源(Critical Resource)
在第一章中我们曾经介绍过,许多硬件资源如打印机、 磁带机等,都属于临界资源,诸进程间应采取互斥方式
,实现对这种资源的共享。
临界区(critical section)
由前所述可知,不论是硬件临界资源还是软件临界资源,多个进程必须互斥地对它进行访问。人们把在每个进程中访问临界资源的那段代码称为临界区``(critical section)
。
同步机制应遵循的规则
为实现进程互斥地进入自己的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则
(1) 空闲让进。
(2) 忙则等待。
(3) 有限等待。
(4) 让权等待。
关中断
关中断是实现互斥的最简单的方法之一。在进入锁测试之前关闭中断,直到完成锁测试并上锁之后才能打开中断。这样,进程在临界区执行期间,计算机系统不响应中断,从而不会引发调度,也就不会发生进程或线程切换。
由此,保证了对锁的测试和关锁操作的连续性和完整性,有效地保证了互斥。
但是,关中断的方法存在许多缺点:
① 滥用关中断权力可能导致严重后果;
② 关中断时间过长,会影响系统效率,限制了处理器交叉执行程序的能力;
③ 关中断方法也不适用于多CPU 系统,因为在一个处理器上关中断并不能防止进程在其它处理器上执行相同的临界段代码。
整型信号量
最初由Dijkstra
把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和signal(S)来访问。很长时间以来,这两个操作一直被分别称为P、V操作
。
记录型信号量
在整型信号量机制中的wait操作,只要是信号量S≤0
,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。
记录型信号量机制则是一种不存在“忙等”现象的进程同步机制。但在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。
为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表指针list,用于链接上述的所有等待进程。
AND型信号量
前面所述的进程互斥问题针对的是多个并发进程仅共享一个临界资源的情况。在有些应用场合,是一个进程往往需要获得两个或更多的共享资源后方能执行其任务。
假定现有两个进程A和B,它们都要求访问共享数据D和E,当然,共享数据都应作为临界资源。
信号量集
在前面所述的记录型信号量机制中,wait(S)
或signal(S)
操作仅能对信号量施以加1或减1操作,意味着每次只能对某类临界资源进行一个单位的申请或释放。当一次需要N个单位时,便要进行N次wait(S)
操作,这显然是低效的,甚至会增加死锁的概率。
此外,在有些情况下,为确保系统的安全性,当所申请的资源数量低于某一下限值时,还必须进行管制,不予以分配。因此,当进程申请某类临界资源时,在每次分配之前,都必须测试资源的数量,判断是否大于可分配的下限值,决定是否予以分配。
利用信号量实现进程互斥
为使多个进程能互斥地访问某临界资源,只需为该资源设置一互斥信号量mutex,并设其初始值为1,然后将各进程访问该资源的临界区CS置于wait(mutex)
和signal(mutex)
操作之间即可。
利用信号量实现前趋关系
设有两个并发执行的进程P1和P2。P1中有语句S1;P2中有语句S2。我们希望在S1执行后再执行S2。为实现这种前趋关系,只需使进程P1和P2共享一个公用信号量S,并赋予其初值为0,将signal(S)操作放在语句S1后面,而在S2语句前面插入wait(S)操作,即
S1;signal(S)
;wait(S);S2
;
管程的定义
系统中的各种硬件资源和软件资源均可用数据结构抽象地描述其资源特性。
由上述的定义可知,管程由四部分组成:
① 管程的名称;
② 局部于管程的共享数据结构说明;
③ 对该数据结构进行操作的一组过程;
④ 对局部于管程的共享数据设置初始值的语句
图2-15是一个管程的示意图。
条件变量 在利用管程实现进程同步时,必须设置同步工具,如两个同步操作原语wait和signal。
在多道程序环境下,进程同步问题十分重要,也是相当有趣的问题,因而吸引了不少学者对它进行研究,由此而产生了一系列经典的进程同步问题,
生产者—消费者
”问题、“哲学家进餐问题
”、 “读者—写者问题
”等等。生产者-消费者模型
利用记录型信号量解决生产者-消费者问题
假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;
利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。
又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息
利用AND信号量解决生产者-消费者问题
对于生产者-消费者问题,也可利用AND信号量来解决,
Swait(empty,mutex)
来代替wait(empty)
和wait(mutex)
;Swait(full,mutex)
代替wait(full)和wait(mutex)
,Ssignal(mutex,empty)
代替Signal(mutex)和Signal(empty)
。利用管程解决生产者-消费者问题
在利用管程方法来解决生产者-消费者问题时,首先便是为它们建立一个管程,并命名为procducer_consumer,或简称为PC。其中包括两个过程:
(1) put(x)
过程。
(2) get(x)
过程。
对于条件变量notfull和notempty,分别有两个过程cwait和csignal对它们进行操作:
(1) cwait(condition)过程
:当管程被一个进程占用时,其他进程调用该过程时阻塞,并挂在条件condition的队列上。
(2) csignal(condition)过程
:唤醒在cwait执行后阻塞在条件condition队列上的进程,如果这样的进程不止一个,则选择其中一个实施唤醒操作;如果队列为空,则无操作而返回。
哲学家问题模型
利用AND信号量机制解决哲学家进餐问题
读者-写者问题模型
利用记录型信号量解决读者-写者问题
为实现Reader与Writer进程间在读或写时的互斥而设置了一个互斥信号量Wmutex。另外,再设置一个整型变量Readcount表示正在读的进程数目。
由于只要有一个Reader进程在读,便不允许Writer进程去写。因此,仅当Readcount=0,表示尚无Reader进程在读时,Reader进程才需要执行Wait(Wmutex)操作。若wait(Wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1
操作。
利用信号量集机制解决读者-写者问题
进程通信是指进程之间的信息交换。
由于进程的互斥与同步,需要在进程间交换一定的信息,故不少学者将它们也归为进程通信,但只能把它们称为低级进程通信。
以信号量机制为例来说明,它们之所以低级的原因在于:
在进程之间要传送大量数据时,应当利用OS提供的高级通信工具,该工具最主要的特点是:
(1) 使用方便。OS隐藏了实现进程通信的具体细节,向用户提供了一组用于实现高级通信的命令(原语),用户可方便地直接利用它实现进程之间的通信。或者说,通信过程对用户是透明的。这样就大大减少了通信程序编制上的复杂性。
(2) 高效地传送大量数据。用户可直接利用高级通信命令(原语)高效地传送大量的数据。
共享存储器系统(Shared-Memory System)
在共享存储器系统中,相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。据此,又可把它们分成以下两种类型:
(1) 基于共享数据结构的通信方式。
(2) 基于共享存储区的通信方式。
管道(pipe)通信系统
为了协调双方的通信,管道机制必须提供以下三方面的协调能力:
① 互斥,即当一个进程正在对pipe执行读/写操作时,其它(另一)进程必须等待。
② 同步,指当写(输入)进程把一定数量(如4 KB)的数据写入pipe,便去睡眠等待,直到读(输出)进程取走数据后再把它唤醒。当读进程读一空pipe时,也应睡眠等待,直至写进程将数据写入管道后才将之唤醒。
③ 确定对方是否存在,只有确定了对方已存在时才能进行通信。
消息传递系统(Message passing system)
在该机制中,进程不必借助任何共享存储区或数据结构,而是以格式化的消息 (message)为单位,将通信的数据封装在消息中,并利用操作系统提供的一组通信命令(原语),在进程间进行消息传递,完成进程间的数据交换。
消息传递系统的通信方式属于高级通信方式,因其实现方式的不同,可进一步分成两类:
(1) 直接通信方式
(2) 间接通信方式
客户机-服务器系统(Client-Server system)
1) 套接字(Socket)
2) 远程过程调用和远程方法调用
如果涉及的软件采用面向对象编程,那么远程过程调用亦可称做远程方法调用。
实际上,远程过程调用的主要步骤是:
(1) 本地过程调用者以一般方式调用远程过程在本地关联的客户存根,传递相应的参数,然后将控制权转移给客户存根;
(2) 客户存根执行,完成包括过程名和调用参数等信息的消息建立,将控制权转移给本地客户进程;
(3) 本地客户进程完成与服务器的消息传递,将消息发送到远程服务器进程;
(4) 远程服务器进程接收消息后转入执行,并根据其中的远程过程名找到对应的服务器存根,将消息转给该存根
(5) 该服务器存根接到消息后,由阻塞状态转入执行状态,拆开消息从中取出过程调用的参数,然后以一般方式调用服务器上关联的过程;
(6) 在服务器端的远程过程运行完毕后,将结果返回给与之关联的服务器存根;
(7) 该服务器存根获得控制权运行,将结果打包为消息,并将控制权转移给远程服务器进程;
(8) 远程服务器进程将消息发送回客户端;
(9) 本地客户进程接收到消息后,根据其中的过程名将消息存入关联的客户存根,再将控制权转移给客户存根;
(10) 客户存根从消息中取出结果,返回给本地调用者进程,并完成控制权的转移。
直接消息传递系统
在直接消息传递系统中采用直接通信方式,即发送进程利用OS所提供的发送命令(原语),直接把消息发送给目标进程。
1) 直接通信原语
(1) 对称寻址方式。
(2) 非对称寻址方式。
2) 消息的格式
3) 进程的同步方式
4) 通信链路
为使在发送进程和接收进程之间能进行通信,必须在两者之间建立一条通信链路。有两种方式建立通信链路。
信箱通信
1) 信箱的结构
信箱定义为一种数据结构。在逻辑上,可以将其分为两个部分:
(1) 信箱头
(2) 信箱体
2) 信箱通信原语
系统为邮箱通信提供了若干条原语,分别用于: (1) 邮箱的创建和撤消。 (2) 消息的发送和接收。
3) 信箱的类型
邮箱可由操作系统创建,也可由用户进程创建,创建者是邮箱的拥有者。据此,可把邮箱分为以下三类:
(1) 私用邮箱。
(2) 公用邮箱。
(3) 共享邮箱。
Hansan
提出,并在RC 4000系统
上实现,消息缓冲队列通信机制中的数据结构
(1) 消息缓冲区。
(2) PCB中有关通信的数据项。
发送原语
然后调用发送原语,把消息发送给目标(接收)进程。发送原语首先根据发送区a中所设置的消息长度a.size来申请一缓冲区i
;
接着,把发送区a中的信息复制到缓冲区i中。为了能将i挂在接收进程的消息队列mq上,应先获得接收进程的内部标识符j,然后将i挂在j.mq上。由于该队列属于临界资源,故在执行insert操作的前后都要执行wait和signal操作。
接收原语
接收进程调用接收原语receive(b),从自己的消息缓冲队列mq中摘下第一个消息缓冲区i,并将其中的数据复制到以b为首址的指定消息接收区内。
如果说,在OS中引入进程的目的是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,
进程的两个基本属性
首先让我们来回顾进程的两个基本属性: ① 进程是一个可拥有资源的独立单位,一个进程要能独立运行,它必须拥有一定的资源;
② 进程同时又是一个可独立调度和分派的基本单位,一个进程要能独立运行,它还必须是一个可独立调度和分派的基本单位。
程序并发执行所需付出的时空开销
为使程序能并发执行,系统必须进行以下的一系列操作:
(1) 创建进程
,系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、I/O设备,以及建立相应的PCB;
(2) 撤消进程
,系统在撤消进程时,又必须先对其所占有的资源执行回收操作,然后再撤消PCB;
(3) 进程切换
,对进程进行上下文切换时,需要保留当前进程的CPU环境,设置新选中进程的CPU环境,因而须花费不少的处理机时间。
线程——作为调度和分派的基本单位
线程
的概念。线程运行的三个状态
与传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态:
(1) 执行状态,表示线程已获得处理机而正在运行;
(2) 就绪状态,指线程已具备了各种执行条件,只须再获得CPU便可立即执行;
(3) 阻塞状态,指线程在执行中因某事件受阻而处于暂停状态,例如,当一个线程执行从键盘读入数据的系统调用时,该线程就被阻塞。
线程控制块TCB
线程控制块TCB
,将所有用于控制和管理线程的信息记录在线程控制块中。 多线程OS中的进程属性
通常在多线程OS中的进程都包含了多个线程,并为它们提供资源。
OS支持在一个进程中的多个线程能并发执行,但此时的进程就不再作为一个执行的实体。多线程OS中的进程有以下属性:
(1) 进程是一个可拥有资源的基本单位。
(2) 多个线程可并发执行。
(3) 进程已不是可执行的实体。
线程已在许多系统中实现,但各系统的实现方式并不完全相同。在有的系统中,特别是一些数据库管理系统
Macintosh和OS/2操作系统
)所实现的是内核支持线程;还有一些系统如Solaris操作系统,则同时实现了这两种类型的线程。内核支持线程KST(Kernel Supported Threads)
为了对内核线程进行控制和管理,在内核空间也为每一个内核线程设置了一个线程控制块,内核根据该控制块而感知某线程的存在,并对其加以控制。当前大多数OS都支持内核支持线程。
这种线程实现方式主要有四个主要优点:
(1) 在多处理器系统中,内核能够同时调度同一进程中的多个线程并行执行;
(2) 如果进程中的一个线程被阻塞了,内核可以调度该进程中的其它线程占有处理器运行,也可以运行其它进程中的线程;
(3) 内核支持线程具有很小的数据结构和堆栈,线程的切换比较快,切换开销小;
(4) 内核本身也可以采用多线程技术,可以提高系统的执行速度和效率。
用户级线程ULT
(User Level Threads)
用户级线程是在用户空间中实现的。对线程的创建、 撤消、同步与通信等功能,都无需内核的支持,即用户级线程是与内核无关的。
在一个系统中的用户级线程的数目可以达到数百个至数千个。由于这些线程的任务控制块都是设置在用户空间,而线程所执行的操作也无需内核的帮助,因而内核完全不知道用户级线程的存在。
使用用户级线程方式有许多优点:
(1) 线程切换不需要转换到内核空间。
(2) 调度算法可以是进程专用的。
(3) 用户级线程的实现与OS平台无关,因为对于线程管理的代码是属于用户程序的一部分,所有的应用程序都可以对之进行共享。
而用户级线程方式的主要缺点则在于:
(1) 系统调用的阻塞问题。在基于进程机制的OS中,大多数系统调用将使进程阻塞,因此,当线程执行一个系统调用时,不仅该线程被阻塞,而且,进程内的所有线程会被阻塞。而在内核支持线程方式中,则进程中的其它线程仍然可以运行。
(2) 在单纯的用户级线程实现方式中,多线程应用不能利用多处理机进行多重处理的优点,内核每次分配给一个进程的仅有一个CPU,因此,进程中仅有一个线程能执行,在该线程放弃CPU之前,其它线程只能等待。
组合方式
ULT/KST 线程
。在组合方式线程系统中,内核支持多个内核支持线程的建立、调度和管理,同时,也允许用户应用程序建立、调度和管理用户级线程。
内核支持线程的实现
在仅设置了内核支持线程的OS中,一种可能的线程控制方法是,系统在创建一个新进程时,便为它分配一个任务数据区PTDA(Per Task Data Area),其中包括若干个线程控制块TCB空间,如图2-19所示。
用户级线程的实现
1) 运行时系统
(Runtime System)
2) 内核控制线程
LWP(Light Weight Process)
。每一个进程都可拥有多个LWP,同用户级线程一样,每个LWP都有自己的数据结构(如TCB),其中包括线程标识符、优先级、状态,另外还有栈和局部存储区等。LWP
也可以共享进程所拥有的资源。LWP可通过系统调用来获得内核提供的服务,这样,当一个用户级线程运行时,只须将它连接到一个LWP上,此时它便具有了内核支持线程的所有属性。这种线程实现方式就是组合方式。
线程的创建
线程的终止
本节结束 2019年10月5日