【问题】
A,B,C,D 四个进程, A 向 buf 里面写数据, B,C,D 向 buf 里面读数据,
当 A 写完,且 B , C , D 都读一次后, A 才能再写。用 P , V 操作实现。
解答:
一个生产者,三个消费者,公用 1 个缓冲区
在这个问题中,不仅生产者与消费者之间要同步,同时每生产一个产品,三个消费者必须并且只能消费一次。
定义四个信号量:
mutexB—— 消费者 B 和生产者之间的互斥信号量,初值为 1 。
mutexC—— 消费者 C 和生产者之间的互斥信号量,初值为 1 。
mutexD—— 消费者 D 和生产者之间的互斥信号量,初值为 1 。
生产者进程
while(TRUE)
{
生产一个产品 ;
// 因为这里需要确认三个消费者都已经消费了
P(mutexB);
P(mutexC);
P(mutexD);
产品送往 buffer();
// 三个消费者可以消费了
V(mutexB);
V(mutexC);
V(mutexD);
}
消费者进程 B ,每个产品,该消费者只能消费一次
while(TRUE)
{
P(mutexB);
从 buffer() 中取出产品 ;
V(mutexB);
消费该产品 ;
}
消费者进程 C ,每个产品,该消费者只能消费一次
while(TRUE)
{
P(mutexC);
从 buffer() 中取出产品 ;
V(mutexC);
消费该产品 ;
}
消费者进程 D, 每个产品,该消费者只能消费一次
while(TRUE)
{
P(mutexD);
从 buffer() 中取出产品 ;
V(mutexD);
消费该产品 ;
}
下面是从网上找来的参考资料:
信号量PV操作
http://hi.baidu.com/superluo/blog/item/f2389618ef01febe4aedbcc3.html
阐述P,V原语的理论不得不提到的一个人便是赫赫有名的荷兰科学家 E.W.Dijkstra。如果你对这位科学家没有什么印象的话,提起解决图论中最短路径问题的Dijkstra算法应当是我们再熟悉不过的了。P,V原语的概念以及P,V操作当中需要使用到的信号量的概念都是由他在1965年提出的。
信号量是最早出现的用来解决进程同步与互斥问题的机制(也可实现进程通信),包括一个称为信号量的变量及对它进行的两个原语操作。信号量为一个整数,我们设这个信号量为:sem。很显然,我们规定在sem大于等于零的时候代表可供并发进程使用的资源实体数,sem小于零的时候,表示正在等待使用临界区的进程的个数。根据这个原则,在给信号量附初值的时候,我们显然就要设初值大于零。
p操作和v操作是不可中断的程序段,称为原语。P,V原语中P是荷兰语的Passeren,相当于英文的pass, V是荷兰语的Verhoog,相当于英文中的incremnet。
且在P,V愿语执行期间不允许有中断的发生。
对于具体的实现,方法非常多,可以用硬件实现,也可以用软件实现。这种信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。
-------------------------------------------------------------
首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
P(S):①将信号量S的值减1,即S=S-1;
②如果S>=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):①将信号量S的值加1,即S=S+1;
②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。
什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。
一般来说,信号量S>=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;
当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;
若S<=0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。
利用信号量和PV操作实现进程互斥的一般模型是:
进程P1 &nbs