生产者和消费者
当只有一个生产者和一个消费者的时候,且只有一个缓冲区
要考虑生产者和消费者两个进程的互斥,还有生产者和消费者进程执行动作的先后顺序。
当只有一个生产者和一个消费者的时候,有n个缓冲区
当有k个生产者和m个消费者的时候,有一个缓冲区
当有k个生产者和m个消费者的时候,有n个缓冲区
要考虑生产者之间的互斥,消费者之间的互斥。
在一个盒子里,混装了数量相等的黑白围棋子。现在用自动分拣系统把黑子、白子分开,设分拣系统有二个进程P1和P2,其中P1拣白子;P2拣黑子。
注意:
规定每个进程每次拣一子当一个进程在拣时,不允许另一个进程去拣。
当一个进程拣了一子时,必须让另一个进程去栋。
试写出两进程P1和P2能并发正确执行的程序。
分析:这是一个有序进行的程序,是同步关系。需设置两个信号量s1,s2来协调他们的活动。
设 s1=1; s2=0;
void white()
{
while(true)
{
wait(s1);
//拣白子
signal(s2);//发消息告知机器该拣黑子了
}
}
void black()
{
while(true)
{
wait(s2);
//拣黑子
signal(s1);//发消息告知机器该拣白子了
}
}
有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。
semaphore empty = 100;// 记录空座位
semaphore mutex = 1;// 作为互斥的访问登记和注销操作
void reader()
{
while(true)
{
wait(empty);
wait(mutex);
// 登记
signal(mutex);
// read
wait(mutex);
// 注销
signal(mutex);
signal(empty);
}
}
和尚打水的一些感想:首先,弄明白有几个进程类,本题肯定是小和尚和老和尚,再弄明白每个进程类是只有一个进程还是有多个进程。本题是肯定是有多个小和尚和多个老和尚。
小和尚提水入缸供老和尚饮用.水缸可以容纳10桶水,太像生产者-消费者的问题了。
水井窄,只能容纳一人使用。说明每次只有一个小和尚在打水。
要在小和尚这个进程设置一个初值为1的信号量。
老和尚从水缸中取水,和小和尚向水缸中倒水是一个互斥事件
要在小和尚、老和尚的进程中设置一个初值为1的信号量。
水桶的数量只有3个,说明小和尚和老和尚的进程数加在一起最多只有3个在运行。要在小和尚、老和尚的进程中设置一个初值为3的信号量。
思考
①:只在小和尚这个进程设置一个初值为1的信号量。
②:在小和尚、老和尚的进程中设置一个初值为1的信号量。
③:要在小和尚、老和尚的进程中设置一个初值为3的信号量。
这三个信号量的对进程互斥的作用。
请用信号量解决以下的“过独木桥”问题:同一方向的行人可连续过桥,当某一方向有人过桥时,另一方向的行人必须等待;当某一方向无人过桥时,另一方向的行人可以过桥。
将独木桥的两个方向分别标记为A和B;并用整形变量countA和countB分别表示A、B方向上已在独木桥上的行人数,初值为0;再设置三个初值都1的互斥信号量:SA用来实现对countA的互斥访问,SB用来实现对countB的互斥访问,mutex用来实现两个方向的行人对独木桥的互斥使用。则具体描述如下:
Var SA,SB,mutex:semaphore:=1,1,1;
CountA,countB:integer:=0,0:
begin
parbegin
processA: begin
wait(SA);
if(countA=0) thenwait(mutex);
countA:=countA+1;
signal(SA);
过独木桥;
wait(SA);
countA:=countA-1;
if (countA=0) then signal(mutex);
signa(SA);
end
processB: begin
wait(SB);
if(countB=0) thenwait(mutex);
countB:=countB+1;
signal(SB);
过独木桥;
wait(SB);
countB:=countB-1;
if (countB=0) then signal(mutex);
signa(SB);
end
parend
end