利用信号量实现进程互斥
为使多个进程互斥的访问某临界资源,须为该资源设置一个互斥信号量mutex,并设初始值为1,然后将各进程访问资源的临界区CS置于wait(mutex)和signal(mutex)之间。
例如用记录型信号量实现两个进程互斥适用一个打印机:
semaphore mutex =1; //表示打印机
begin
parbegin
p1: begin
repeat
… …
wait(mutex);
使用打印机
signal(mutex);
… …
until false;
end
p2: begin
repeat
… …
wait(mutex);
使用打印机
signal(mutex);
… …
until false;
end
parend
end
利用信号量实现前驱关系
假设有两个并发执行的进程P1、P2,P1中有语句S1,P2中有语句S2,希望在S1执行后执行S2。解决办法是:使进程P1、P2共享一个公共信号量S,并对S赋值为0。
进程P1: S1;
signal(S);
进程P2: wait(S);
S2;
由于S初始值是1,进程P2的wait操作是无法通过的,所以S2语句执行不了。而进程P1没有wait操作,可以直接执行S1语句,然后执行signal语句,S++,这时进程P2可以全部执行完了。
根据第一个简单的例子,可以推出复杂前驱关系时的代码:
第一步:假设S1到S2的共享信号量为a
semaphore a = 0;
begin
parbegin
begin S1; signal(a); end;
begin wait(a); S2; end;
parend
end
第二步:假设S1到S3的共享信号量为b
semaphore a, b = 0;
begin
parbegin
begin S1; signal(a); signal(b); end;
begin wait(a); S2; end;
begin wait(b); S3; end;
parend
end
第三步:假设S2到S4的共享信号量为c
semaphore a, b, c = 0;
begin
parbegin
begin S1; signal(a); signal(b); end;
begin wait(a); S2; signal(c); end;
begin wait(b); S3; end;
begin wait(c); S4; end;
parend
end
第四步:假设S2到S5的共享信号量为d
semaphore a, b, c, d = 0;
begin
parbegin
begin S1; signal(a); signal(b); end;
begin wait(a); S2; signal(c); signal(d); end;
begin wait(b); S3; end;
begin wait(c); S4; end;
begin wait(d); S5; end;
parend
end
第五步:假设S3到S6,S5到S6,S4到S6的共享信号量分别为e、f、g
semaphore a, b, c, d, e, f, g = 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(g); end;
begin wait(d); S5; signal(f); end;
begin wait(e); wait(f); wait(g); end;
parend
end
利用记录型信号量实现同步
p1,p2两进程因合作完成一项任务而共用一个变量x。进程p2将处理结果送入x,进程p1将x的结果打印。如何实现合作关系?
semaphore empty=1; //变量x可赋值使用,即P1的print(x)已完成
semaphore full=0; //变量x已赋值,即P1可print(x)
begin
parbegin
p1: begin
repeat
… …
wait(full);
print(x);
signal(empty);
… …
until false;
end
p2: begin
repeat
… …
wait(empty);
x:=处理结果;
signal(full);
… …
until false;
end
parend
end
这里利用了信号量机制实现了同步模式,和生产者消费者模型类似,防止了死锁的发生。在记录型信号量多资源共享发生死锁的时候是用AND型信号量进行处理的,这里说明了记录型信号量解决死锁问题的方法。