一、生产者–消费者问题
生产着消费者问题即多个生产者和消费者对n个缓冲区的使用。
若不考虑互斥、同步问题会导致counter计数错误。
- 无论生产者、消费者使用缓冲池时应保证互斥使用(互斥信号量mutex )
- 生产者和消费者间交叉有序:
①有序的控制最根源在产品数量上。
②设置两个信号量:分别针对生产者、消费者设置不同的信号量,empty和full分别表示缓冲池中空缓冲池和满缓冲池(即产品)的数量。
- 利用记录型信号量解决生产者–消费者问题
//mutex: 生产者间,消费者间互斥使用缓冲区的互斥信号量
//empty: 缓冲区的空闲容量
//full: 缓冲区的已占容量
buffer: array[0, ..., n-1] of item;
in, out: integer := 0, 0;
var mutex, empty, full: semaphore := 1, n, 0;
producer: //生产者
begin
repeat
...
produce an item in nextp; //生产一个产品放入nextp
...
//进入区
wait(empty);
wait(mutex);
//临界区
buffer(in) := nextp;
in := (in+1) mod n;
//退出区
signal(mutex);
signal(full);
until false;
end
consumer: //消费者
begin
repeat
//进入区
wait(full);
wait(mutex);
//临界区
mextc := buffer(out);
out := (out+1) mod n;
//退出区
signal(mutex);
signal(empty);
//剩余区
consume the item in nexc; //消费nextc中的产品
until false;
end
注意:
1)每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对出现。
2)控制顺序的资源信号量empty和full的wait和signal操作,需要成对出现在不同的程序中。
3)在每个程序中的多个wait操作顺序不颠倒。应先申请资源信号量(wait操作),后申请互斥信号量(wait操作),否则可能引起进程死锁。
- 利用AND信号量解决生产者–消费者问题
//mutex: 生产者间,消费者间互斥使用缓冲区的互斥信号量
//empty: 缓冲区的空闲容量
//full: 缓冲区的已占容量
buffer: array[0, ..., n-1] of item;
in, out: integer := 0, 0;
var mutex, empty, full: semaphore := 1, n, 0;
producer: //生产者
begin
repeat
...
produce an item in nextp; //生产一个产品放入nextp
...
//进入区
Swait(empty, mutex); //不必考虑信号量先后问题
//临界区
buffer(in) :=