您的位置:首页 > 其它

pv操作实现多进程同步和互斥

2013-04-07 19:15 1391 查看
本篇文章,讲解了PV操作的作用,举了两个情景模拟pv操作的应用原理,同时讲解了PV操作涉及到的基本概念,并且在文章的最后用伪代码写了pv操作过程。

要理解PV操作,请先看两个场景:

场景1:飞机场售票窗口进程

Process Pi(i=1,2,3,…,n)

Begin

查找当天机票剩余量A

If A>1 then

A=A-1;

售出一张票

Else 输出票以售完

End


若同时有5个窗口执行该程序,如果5个程序同时并发执行,同时取到相同的票数(实际情况中:用锁就能解决该问题,不会取到相同的票数,此处只是为说明pv操作),则售了5张票,而实际票数只减了1张。

场景2:进程A向缓存中写数据(缓存只存一条数据),进程B从缓存存数据。如果在B未取走数据前就写入数据,数据会被覆盖;若A还没写入新数据前B写入一次数据,则会读取到旧数据,怎么保证两个进程能够同步执行?

情景一为互斥问题,当一个进程读取并修改数据的时候,另一个进程不能读取数据;情景二为同步问题,只有在进程A写入数据后,B才能读数据,否则可能读到空数据或者重复数据;B读取完,A才能写入数据,否则可能数据还没有读的时候就被覆盖掉。

使用PV操作可以解决上面的两个问题,pv操作通过观察信号量,从而控制多个进程间同步或互斥使用资源。

理解PV操作需要理解几个重要的概念:临界区,P操作,V操作,同步和互斥。

进程的互斥:若干个进程都要访问某一共享资源时,任何时刻最多只允许一个进程使用该资源,其他要使用该资源的进程必须等待,知道该资源的占用者释放进程。

进程的同步:并发进程间存在一种制约关系,一个进程的执行依赖另一个进程的消息,当一个进程没有得到另一个进程的消息时等待,知道消息到达才被唤醒。

临界区:当N个进程都要访问同一个变量时,我们把与共享变量有关的程序段成为临界区。所有涉及该变量的临界区成为相关临界区。

信号量:表示临界区的进程是否可以往下执行,用S signal 代表信号量 ,s>0,代表当前变量或资源可以使用,该进程可以执行;S=0,表示当前无资源,当前进程不可往下执行;s<0表示当前有等待使用资源的进程,并且该负数的绝对值代表等待资源的进程数

p操作:判断调用P操作的进程是否可以获得资源并往下执行,如果信号量减一后大于0,将会往下执行,否则继承进入等待队列;

用代码表示:

Procedure P(Var S:Semaphore);

Begin

s=s-1;

If s<0 then W(s);

End;{P}


V操作:进程释放一个变量或资源,信号量加一,若等待队列有进程,则释放一个等待进程(该进程获取资源并执行)

Procedure V(Var S:Semaphore);

Begin

s=s+1

if S<=0 then r(s)

end


那么了解了PV操作和相关的概念后,我们可以试着用PV操作解决文章开始的两个场景了:

解决场景一:将PV操作将如到场景一的伪代码中

Begin

S:semaphore  //定义信号量

S=1;

Process Pi(i=1,2,3,…,n)

Begin

查找当天机票剩余量A

P(S);           //进行P操作,当前的信号量减1大于等于0,则继续进行,否则等待资源

If A>1 then

A=A-1;

V(S)             //将当前变量或资源释放,将信号量加一,结果如果小于等于0,则唤醒一个进程

售出一张票

Else 输出票以售完

End

End


那么此时,由于将信号量设置为1,只能有一个进程访问并修改机票数量,因此不会出现问题。

有此可见,当信号量为正时,信号量的数值代表有几个可用资源,为0时,表示当前没有可用资源,为负值时说明当前有进程在等待资源。

解决场景二:

Begin

Buffer:integer

SA,SB:semaphore;

SA=1,SB=0;//定义A进程的信号量和B进程的信号量

Process A

Begin

L1:  向缓存中写入一个数据Data;

P(SA);         //进行P操作,判断当前进程A是否可以向缓存写入数据

Buffer=Data;

V(SB);              //A进程写入说后,将B进程的信号量加一,告诉B进程可以进行读数据了

Goto L1;

End ;

Process B

Begin

L2:     P(SB);                                         //进行P操作,判断当前进程B是否可以从缓存读数据

从缓存取出一个数据Data;

V(SA);                 //读完数据后,将A进程的信号量加一,告诉A进程可以写入数据了

用取出的数据进行计算;

Goto L2;

End

End


PV操作解决了多个进程间共享数据和资源时,误操作的问题,保证了安全的共享资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: