操作系统学习笔记(二)
进程的基本概念
进程的的三种基本状态:就绪状态,执行状态,阻塞状态。
就绪状态:进程已经获得了所需的资源,只要得到了CPU就可以立即执行,通常情况下系统中会有多个就绪进程,处在就绪队列。
执行状态:进程已经获得CPU,正处在执行状态。
阻塞状态:正在执行的进程由于发生某事而无法继续执行,便放弃处理机而处于暂停的状态。
三状态转换图。
挂起状态:因某些需要,需要经一些进程挂起而不接受调度。
进程控制块:
为了描述和及控制进程的运行,系统为每个进程定义了一个数据结构--进程控制块PCB(Process Control Block)。系统总是通过PCB来对进程进行控制,PCB是进程存在的唯一标志。
PCB中包含的信息:
(1)进程标识符
(2)处理机状态
(3)进程调度信息
(4)进程控制信息
进程控制
进程控制一般由OS的内核中的原语(Primitive)实现,原子操作(Action Operation)在执行过程中不允许被中断。
进程创建的步骤,即操作系统调用原语Create()按下述步骤创建新进程。
(1)申请空白PCB
(2)为进程分配资源
(3)初始化进程控制块
(4)将新进程插入就绪队列
进程的阻塞与唤醒(原语Block(),Wakeup()必须成对使用)
(1)请求系统服务
(2)启动某种操作
(3)新数据尚未到达
(4)无新工作可做
进程同步
进程同步的主要任务就是对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能够有效的共享资源和相互合作。
进程间的两种制约关系:
间接制约:多出现在同一系统中,如两个进程共享打印机资源。
直接制约:如进程A要给进程B输入数据。
临界资源:如打印机,磁带机等。
人们把每个进程中访问临界资源的那段代码成为临界区,将检查某资源是否被访问的代码成为进入区,访问后将临界区标志恢复为未被访问的代码叫做退出区。
因此,可以把一个访问临界资源的循环进程描述如下:(书中的算法都是用Pascal语言写的)
repeat entry section critical section exit section remainder section until false
同步机制应该遵循的规则:空闲让进,忙则等待,有限等待,让权等待。
信号量机制:
整型信号量:
最初由Dijkstra把整型变量定义为一个用于表资源数目的整型量S,它与一般整型量不同,仅可通过两个标准的原子操作(P、V操作)wait(S)和Signal(S)来访问。
操作描述:
wait(S):while S<=0 do no-op;//如果资源为空,则循环等待
S:=S-1;//一旦有资源则使用资源,资源数目减一
signal(S): S:=S+1;//生产资源。
记录型信号量:
该机制中除了一个表示资源数目的变量Value之外,还增加了一个进程链表L,用于链接上述所有等待的进程
该记录型的数据结构表示为:
type semaphore = record value:integer; L:list of process end 则wait(S)和Signal(S)操作可描述为: procedure wait(S)//请求资源 var S:semaphore;//声明一个数据结构 begin S.value = S.value - 1; //请求一个单位资源,S.value的绝对值表示已阻塞的进程数目。 if S.value < 0 then block(S.L);//如果该资源已分配完毕,则让其阻塞,放弃处理机,并插入到信号量链表 end procedure signal(S)//释放资源 var S: semaphore; begin S.value = S.value + 1;//释放一个单位资源,若释放后S.value仍然是负值则说明仍有进程在等待,则唤醒S.L链表中的第一个等待进程 if S.value <= 0 then wakeup(S.L); end 若S.value初值为1,则信号量转为互斥信号量,只允许一个进程访问临界资源。
AND型信号量
上述各进程问题针对进程之间共享一个临界资源而言。但有些时候一个进程需要获得两三个资源方可执行。设进程A,B都要求访问数据D和E。则为这两个临界资源分别设置互斥的信号量Dmutex,Emutex = 1;则在两个进程中都需要对Dmutex和Emutex进行操作,即
process A: process B:
wait(Dmutex); wait(Emutex);
wait(Emutex); wait(Dmutex);
但这样交替执行四个操作的时候,会发生死锁。故该AND同步机制的基本思想就是将进程所需资源一次性分配给进程,使用完后一起释放。即在wait操作中增加
AND的条件,成为AND同步,或成为同步wait操作,即Swait():
Swait(S1,S2,……,Sn) if Si >= 1 and …… and Sn >= 1 then for i:= 1 to n do Si:= Si - 1; endfor else //等待 endif Ssignal(S1,S2,……,Sn) for i:= 1 to n do Si:= Si + 1; //唤醒等待进程 endfor
信号量集
记录型变量一次只能获得或释放一个单位资源,当一次需要N个单位资源的时候显得低效。因此,当资源数量低于某一下限值时便不予以分配。因此Swait操作可描述如下
,S为信号量,d为需求值,t为下限值。Swait可描述为
Swait(S1,t1,d1,...,Sn,tn,dn) if S1 >= t1 and ... Sn >= tn then for i:=1 to n do Si:=Si - di; endfor else //阻塞等待 endif for i:=1 to n do Si:=Si + di; //释放资源 endfor; Ssignal(S1,t1,d1,...,Sn,tn,dn)
利用信号量实现的前趋关系:
如图
Var a,b,c,d,e,f,g: semaphore:=0,0,0,0,0,0,0; begin parbegin begin S1; signal(a);signal(b);end; begin wait(a);S2;signal(c);signal(d);end; begin wait(b);S3;signal(e);end; begin wait(c);S4;signal(f);end; begin wait(d);S5;signal(g);end; begin wait(e);wait(f);wait(g);S6;end; parend end
管程机制
管程是由代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成的一个操作系统的资源管理模块。
管程由四部分组成:
1 管程的名称
2 局部于管程内部的数据结说明
3 对数据结构进行操作的一组过程
4 对局部于管程内部的共享资源设置初始化值的语句
条件变量:管程中对每个条件变量都须予以说明:
Var x,y:conditon x.wait;//正在调用管程的进程因x条件的需要被阻塞或挂起。调用x.wait将自己插入到x条件的等待队列上,并释放管程,直到x条件变化。 x.signal;//正在调用管程的进程发现x条件发生变化,则调用x.signal,重新启动一个因x条件而阻塞或挂起的进程