一、进程互斥与同步

1、进程间两种形式的制约关系

(1)间接相互制约关系——源于资源共享(例如打印机)
(2)直接相互制约关系——源于进程合作(一组进程如果它们单独不能正常进行但并发可以进行称这种现象为进程合作cooperation,例如分布式系统)

2、临界资源

临界资源(Critical Resource) :把段时间内只允许一个进程访问的资源称为临界资源或独占资源。
临界区(Critical Section):每个进程中访问临界资源的那段代码称为临界区。

二、信号量机制*

信号量是OS提供的管理公有资源的有效手段。
信号量是一个整数,当信号量大于等于零时,代表可供并发进程使用的资源数量,当信号量小于零时,表示处于阻塞态进程的个数。

如何保证临界区只有一个资源进入?
给临界区资源加互斥锁,可以保证临界区资源释放时,只有一个线程获得临界区资源。

Wait操作:
申请资源,减量操作,S.value = S.value-1
当S.value < 0时,表示资源分配完,进行自我阻塞。

Signal操作:
释放资源,增量操作,S.value = S.value+1 
当S.values<0,唤醒S.L链表中的等待进程。

除了赋值只有两个操作,访问之前需要进行wait操作,访问之前需要进行wait操作

1.利用信号量实现进程互斥(模式)

为使多个进程互斥的访问某临界资源,须为该资源设置一互斥信号量mutex,并设其初始值为1,然后将各进程访问资源的临界区CS置于wait(mutex)和signal(mutex)之间即可。

// 用信号量机制实现互斥的模式
Var mutex:semaphore :=1;
begin
parbegin
process 1: begin
repeat
wait(mutex);
critical section
signal(mutex);
remainder section
until false;
end
parend

// wait(mutex)和signal(mutex)必须成对出现
process 2:begin
repeat
wait(mutex);
critica section
signal(mutex);
remainder section
until false;
end

例1:用记录型信号量实现两个进程互斥使用一台打印机

Var mutex: semaphore =1; //表示打印机
begin
parbegin
p1: begin
repeat
...
wait(mutex);
使用打印机
signal(mutex);
...
until false;
end
parend

p2: begin
repeat
...
wait(mutex);
使用打印机
signal(mutex);
...
until false;
end

2.利用信号量实现前驱关系(模式)

设有两个并发执行的进程P1和P2,P1中有语句S1,P2中有语句S2,希望在S1执行后再执行S2。
使进程P1和P2共享一个公用信号量S,并赋予其初值为0。

操作系统核心之 处理器管理_os

进程P1:S1;
               signal(S);
进程P2:wait(S) ;
               S2;

操作系统核心之 处理器管理_OS_02

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; sigpal(f); end;
begin wait(d); S5; signal(g); end;
begin wait(e); wait(f); wait(g); S6; end;
parend
end

3.利用记录型信号量实现同步(模式)

P1 , p2两进程因合作完成一项任务而共用一个 变量X。进程p2将处理结果送入x ;进程P1将x的结果打印。
即: p2 : x=处理结果;
     p1 : Print(x);
例2:如何实现该合作关系?

// 变量x可赋值使用,即P1的print(x)已完成
// 变量x已赋值,即P2可print(x)
Var empty: semaphore := 1;
full: semaphore :=0;
begin
parbegin
pl: begin
repeat
...
wait(full);
print(x);
signal(empty);
...
until false;
end
parend

p2: begin
repeat
...
wait(empty);
x=处理结果;
signal(full);
...
until false;
end

例3:进程P1、P2、P3、P4和P5的前趋图如下,若用PV操作控制进程P1~P5并发执行的过程,则需要设置6个信号量S1、S2、S3、S4、S5和S6,且信号量S1~S6的初值都等于零。下图中a和b处应分别填写(C);c和d处应分别填写(B),e和f处应分别填写(C)。

操作系统核心之 处理器管理_os_03 操作系统核心之 处理器管理_OS_04

(1)  A. P(S1) P(S2)和P(S3) P(S4)        B. P(S1) V(S2)和P(S2) V(S1)
           C. V(S1) V(S2)和V(S3) V(S4)        D. P(S1) P(S2)和V(S1) V(S2)
(2)  A. P(S1) P(S2)和V(S3) V(S4)        B. P(S1) P(S3)和V(S5) V(S6)
           C. V(S1) V(S2)和P(S3) P(S4)        D. P(S1) V(S3)和P(S2) V(S4)
(3)  A. P(S3) P(S4)和V(S5) V(S6)        B. V(S5) V(S6)和P(S5) P(S6)
           C. P(S2) P(S5)和P(S4) P(S6)        D. P(S4) V(S5)和P(S5) V(S6)

题解:a处就是P1指向的P3和P4,b处就是P2指向的P3和P5,看选项所以应该都是V,故V(S1) V(S2)和V(S3) V(S4)。cd处有P1和P2为前驱,P4P5为后继,应该是PPVV的形式,S1S2S3S4是P1P2发出,故P(S1) P(S3)和V(S5) V(S6)。ef处只有前驱所以是PPPP,故P(S2) P(S5)和P(S4) P(S6)。

三、死锁*

死锁:是指多个进程在运行过程中因争夺资源而造成的一种僵局当进程处于这种状态时,若无外力作用,它们都将无法再向前推进。

1、产生死锁的原因

(1)竞争资源引起进程死锁

当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足诸进程的需要时,会弓|起诸进程对资源的竞争而产生死锁。

可把系统中的资源分为两类:
a.可剥夺性资源:资源分配给进程后可以被高优先级的进程剥夺。如CPU、主存。
b.不可剥夺性资源:分配给进程后只能在进程用完后才释放的资源。如磁带机、打印机等。

(2)进程间推进顺序非法

进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生死锁。

2、产生死锁的必要条件*

(1)互斥条件
(2)请求和保持条件
(3)不剥夺条件
(4)环路等待条件

(1)互斥条件
进程访问的是临界资源,即在一段时间内某资源只由一个进程占用。如果此时还有其他进程请求该资源,则请求者只能等待,直至占有该资源的进程用完释放。

(2)请求和保持条件
一进程在请求新的资源的同时,保持对已分配资源的占有。

(3)不剥夺条件
指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

(4)环路等待条件
指在发生死锁时,必然存在一个进程——资源的环形链。

例1:某系统中有3个并发进程,都需要同类资源4个,试问该系统不会发生死锁的最少资源数是( B )
A.9    B.10    C.11    D.12

题解:3个并发进程,需要资源4个,3个进程*(4个资源-1)+1=10个资源,不会发声死锁,为什么呢?大家都是少一个所以来加了1个资源的时候都可运行但是不会发生死锁,9个谁也不释放可能发生死锁,11或12会发生竞争。

例2:假设某计算机系统中资源R的可用数为6,系统中有3个进程竞争R,且每个进程都需要i个R,该系统可能会发生死锁的最小i
值是(C)。若信号量S的当前值为-2,则R的可用数和等待R的进程数分别为(D)。
A.1    B.2    C.3    D.4
A.0、0    B.0、1    C.1、0    D.0、2

题解:系统中可用数是6,并且有3个进程竞争R,那么当只有3个进程都竞争R的时候就可能会发生死锁。当前信号量是-2,也就是说有两个进程在阻塞状态,那么如果只有两个进程那么可用的就是0,等待(阻塞)状态的进程就是2。

3、处理死锁的基本方法*

在系统中已经出现死锁后,则应及时检测到死锁的发生,并采取适当措施来解除死锁。

目前处理死锁的方法可归结为四种:
(1)预防死锁
(2)避免死锁
(3)检测死锁
(4)解除死锁

(1)预防死锁
是一种较简单和直观的事先预防方法。该方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件的一个或几个,来预防
发生死锁。
例如:摒弃“请求和保持”条件;摒弃“不剥夺”条件(用版本号);摒弃“环路等待”条件(不让其形成环)

(2)避免死锁
该方法同样是属于事先预防的策略,这种方法不是预先加上各种限制条件以预防产生死锁的可能性,而是用某种方法去防止系统进入不安全状态,使死锁不致于最终发生。

银行家算法避免死锁(银行家算法是操作系统中相对抽象的算法,后面会单独成章)

(3)检测死锁
这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区。

此方法允许系统在运行过程中发生死锁,但可通过系统所设置的检测机构,及时的检测出死锁的发生,,并精确的确定与死锁有关的进程和资源;然后采取适当的措施,从系统中将已发生的死锁清除掉。

(4)解除死锁
是与死锁检测相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。

常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测与解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。