}
解法3(6)
P6()
{
p(s6);
p(s6);
p(s6);
┆
}
4.4 经典互斥同步问题
多道程序环境中的进程同步是一个非常有趣的问题,吸引了很多学者研究,从而产生了一系列经典进程同步问题。
1. 生产者—消费者问题
生产者—消费者问题是最著名的进程同步问题。它描述了一组生产者进程向一组消费者进程提供产品,它们共享一个有界缓冲池。缓冲池中的每个缓冲区可以存放一个产品,生产者进程不断生产产品并将产品放入缓冲池中,消费者进程不断从缓冲池内取出产品并消费。
生产者—消费者问题示意图
同步关系有:当缓冲池满时生产者进程需等待,当缓冲池空时消费者进程需等待。诸进程应互斥使用缓冲池。
用信号量解决生产者—消费者问题
设置两个同步信号量empty、full,其初值分别为n、0。
有界缓冲池是一个临界资源,还需要设置一个互斥信号量mutex,其初值为1。
生产者—消费者问题的同步描述如下:
生产者 消费者
生产一个产品;
p(empty);
p (mutex);
将一个产品送入缓冲区;
v (mutex);
v(full);
p (full);
p (mutex);
从缓冲区中取一个产品;
v (mutex);
v (empty);
消费一个产品;
注意
无论在生产者进程还是在消费者进程中,P操作的次序都不能颠倒,否则将可能造成死锁。
颠倒生产者进程中的P操作
2.读者—写者问题
一个数据对象(如文件或记录)可以被多个并发进程所共享,
其中有些进程只要求读数据对象的内容,而另一些进程则要求修改或写数据对象的内容,
允许多个读进程同时读此数据对象,
但是一个写进程不能与其他进程(不管是写进程还是读进程)同时访问此数据对象。
读者—写者问题分类
读者优先:当写者提出存取共享对象的要求后,仍允许新读者进入。
写者优先:当写者提出存取共享对象的要求后,不允许新读者进入。
下面给出读者优先的读者写者问题解。
用信号量解决读者-写者问题
为解决读者写者问题,应设置两个信号量和一个共享变量:
互斥信号量mutex,用于使读进程互斥地访问共享变量readcount,其初值为1;
写互斥信号量writer,用于实现写进程与读进程的互斥以及写进程与写进程的互斥,其初值为1;