生产者-消费者问题(互斥、同步)
1.多个生产者和消费者对缓冲区的使用,无论生产者、消费者使用缓冲池时应保证互斥使用(互斥信号量mutex)
2.生产者和消费者之间交叉有序:(1)有序的控制最根源在产品数量上。(2)设置两个信号量:分别针对生产者、消费者设置不同的信号量,empty和full表示缓冲池中空缓冲和满缓冲池(即产品)的数量。(empty和full两者有天然的数量关系,在PV控制下值不段变化,但在值等于0的点上时控制顺序的关键)
Procuder: Consumer:
repeat repeat
…… ……
procuder an item in nexp; wait(full);
wait(empty); wait(mutex);
wait(mutex); nextc:=buffer(out);
buffer(in):=nexp; out:=(out+1)mod n;
in:=(in+1)mod n; signal(mutex);
signal(mutex); signal(empty);
signal(full); consume the item in nexc;
until false; until false;
检查:
1.每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对的出现。
2.控制顺序的信号量empty和full的wait和signal操作,成对的出现在不同的进程中。
3.在每个程序中的多个wait操作顺序不能颠倒,并且应先执行对资源信号量的wait操作,再执行对互斥信号量的wait操作,否则可能引起进程死锁。
4.模拟交替执行过程,检查控制是否正确。
两个生产者两个消费者同步模拟分析:
*利用AND信号量解决
*利用管程解决
哲学家进餐问题(互斥)
相邻两位不能同时进餐;最多只能有两个人同时进餐。
1.记录型信号量解决哲学家进餐问题:
筷子是临界资源,为实现对筷子的互斥使用,用一个信号量表示一只筷子,五个信号量构成信号量数组。
semaphore chopsticks[5]={1、1、1、1、1};所有信号量被初始化为1;
repeat
wait(chopstick[i]);
wait(chopstick[(i+1)mod5]);
……
eat
……
signal(chopstick[i]);
signal(chopstick[(i+1)mod5]);
……
think;
util false;
2.就餐死锁问题
使五个信号量chopstick均为0,再去拿右边的筷子的时候将因无筷子可拿而无限等待。
解决方法:(1)数量控制:限制并发执行的进程数(至多只允许有四位哲学家同时去拿左边的筷子,保证有一位能够进餐,并在进餐完成后同时释放两只筷子,从而使更多的哲学家能够进餐)
(2)一刀切:仅当哲学家的左右两只筷子均可用时,才允许他拿起筷子进餐——采用AND信号量。
Var chopstick: array[0,1,2,3,4] of semaphore:=(1,1,1,1,1);
Process i;
repeat;
think;
Swait(chopstick[(i+1) mod 5],chopstick[i]);
eat;
Ssignal(chopstick[(i+1) mod 5],chopstick[i]);
util false;
(3)IF控制编程
规定奇数号哲学家先拿他左边的筷子然后再去拿右边的筷子;偶数号的哲学家则相反,保证有一个哲学家能够同时获得两只筷子而进餐。
if I mod 2=0
……
else
……
读者-写者问题(有条件的互斥)
- 一个数据文件被多个进程共享, Reader进程只要求读文件,Writer进程要求写入内容。
- 合理的同步关系是:(1)多个读进程可以同时读;(2)Writer进程与其他任何进程(包括Reader进程或其他Writer进程)不允许同时访问进程。
读者之间不需要互斥的要求;
只有第一个进程进行互斥判断;只要有一个“读进程”在读就不释放,“写进程”就不能写(一种读者优先的方式)
Reader:
repeat
wait(rmutex);
if Readecount=0
then wait(wmutex);
Readecount:=Readecount+1;
signal(rmutex);
……
perform read operation;
……
wait(Rmutex);
Readecount:=Readecount-1;
if Readecount=0;
then signal(wmutex);
signal(rmutex);
写着之间需要互斥的要求;(判断互斥信号量)
Writer:
repeat
wait(wmutex);
写入文件;
signal(wmutex);
util false;