操作系统:信号量与PV原语

操作系统:信号量与PV原语

一、信号量的提出

1965 年,荷兰学者Dijkstra 提出的信号量(Semaphores)机制是一种卓有成效的进程同步工具。在长期且广泛的应用中,信号量机制又得到了很大的发展,它从整型信号量经记录型信号量,进而发展为“信号量集”机制。现在,信号量机制已被广泛地应用于单处理机和多处理机系统以及计算机网络中。

二、信号量的原子操作

要准确理解信号量的两个原子操作PV,有几个问题是绕不过的,第一,PV为什么叫PV?第二,PV所针对的信号量类型支持什么样的能力。

在第一章时我们提到,信号量以及其机制是荷兰学者Dijkstra提出的,P和V是来源于两个荷兰语词汇,P:passeren,中文译为”通过”;V:vrijgeven,中文译为”释放”。知道这事情,我们就不必再纠结与操作系统教材中为何说P是Wait,V是Signal,乍一看太搞笑了。理解了PV的原始含义,那我们后面把PV改成WS的时候,请各位也不要见怪。

第二,信号量的类型。最初基础的整形信号量,实际上是不能完美的实现信号量机制的,在整型信号量机制中的wait操作,只要是信号量S≤0,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。基于整形信号量的改进型:记录型信号量,信号量对象中,会有两个数据项:1)表示资源数目的整形变量,2)进程链表指针,用于链接所有的等待进程。

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;

if S.value<0 then block(S.L);

end

procedure signal(S)

var S: semaphore;

begin

S.value:=S.value+1;

if S.value<=0 then wakeup(S.L);

end

三、信号量来实现前趋关系

可利用信号量来描述程序或语句之间的前趋关系。设有两个并发执行的进程P1和P2。P1中有语句S1;P2中有语句S2。我们希望在S1执行后再执行S2。为实现这种前趋关系,我们只须使进程P1和P2共享一个公用信号量S,并赋予其初值为0,将signal(S)操作放在语句S1后面;而在S2语句前面插入wait(S)操作,即在进程P1中,用S1;signal(S);在进程P2中,用wait(S);S2;由于S被初始化为0,这样,若P2先执行必定阻塞,只有在进程P1执行完S1;signal(S);操作后使S增为1时,P2 进程方能执行语句S2 成功。

在使用信号量来控制程序或者语句之前的前趋关系时,每段程序执行前后,会操作信号量,满足自己的Wait条件时,开始本段程序的执行,执行完成后,对依赖本段程序的信号量执行signal操作。

四、已知前趋图如何设计信号量

已知如下前趋图:

问题:需要设置几个信号量?分别如何控制,才能实现此前趋图。

推理:从前面信号量应用于前趋图的介绍可知,信号量控制的程序的进入与退出,我们来看图中,代表程序的进入与退出的,是各进程节点之间的连接线。则我们将每段连接线,设定为一个信号量。如下图:

基于此方式设置了5个信号量S1~S5。那我们来看一下每个进程要干的事情。在描述之前,我们用标准的信号量控制段方式来声明一个进程的工作模型,WPS模型,W等待所需要的前置条件,P处理进程工作,S设置需要释放的条件信号量。

则P1:W(NULL)-P(ANY)-S(S1,S2)

则P2:W(S1,S3)-P(ANY)-S(S4)

则P3:W(S2)-P(ANY)-S(S3,S5)

则P4:W(S4,S5)-P(ANY)-S(NULL)

这次清晰了吧。

综述:

应用信号量实现前趋图的关键点:第一,理解信号量是用来控制程序段的,则PV分别在程序开始与程序结束操作。第二:信号量的设置方式,简单一点,是将前趋图的每个线段,设置为一个信号量。然后使用WPS模型,逐个写出进程的控制逻辑。完毕。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注