生产者消费者
2.6 设有三个进程 A、B、C,其中 A 与 B 构成一对生产者与消费者(A 为生产者,B 为消费者),共享一个由 n 个缓冲块组成的缓冲池;B 与 C 也构成一对生产者与消费者(此时 B 为生产者,C 为消费者),共享另一个由 m 个缓冲块组成的缓冲池。用 P、V 操作描述它们之间的同步关系。
公用信号量mutex1;mutex2初值1;用于临界区互斥;
生产者私用信号量empty1;empty2;初值是n,m指示空缓存数目;
消费者私用信号量full1,full2;初值0;指示满缓冲区数目;
整形量i,j,a,b初值均为0,i指示缓冲区序号头,j指示满缓冲区头指针;
semaphore mutex1 = 1, empty1 = n, full1 = 0;
semaphore mutex2 = 1, empty2 = m, full2 = 0;
void A()
{
while(1)
{
produce next product1;
p(empty1);
p(mutex1);
buffer1[i] = product1;
i = (i + 1) % n;
v(mutex1);
v(full1);
}
}
void B()
{
while(1)
{
p(full1);
p(mutex1);
product = buffer1[j];
j = (j + 1) % n;
v(mutex1);
v(empty1);
Consume product
Produce next product2;
p(empty2);
p(mutex2);
buffer2[a] = product2;
a = (a + 1) % m;
v(mutex2);
v(full2);
}
}
void C()
{
while(1)
{
p(full2);
p(mutex2);
product = buffer2[b];
b = (b + 1) % m;
v(mutex2);
v(empty2);
Consume the product;
}
}
int main()
{
parbegin(A(), B(), C());
}
面包师
面包师有很多面包和蛋糕,由 n 个销售人员销售。每个顾客进店后先取一个号,并且等着叫号。当一个销售人员空闲下来,就叫下一个号。请分别编写销售人员和顾客进程的程序。
面包师问题
semaphore mutex_s =1 //店员叫号互斥
semaphore mutex_c =1 //顾客取号互斥
semaphore sala = n //店员人数
semaphore customer =0 //顾客数
int count_c =0 //顾客取号数
int count_s =0 //店员叫号数
void customer()
{
P(mutex_c) //申请取号
count_c++; //取号
V(mutex_c) //释放取号资源
V(customer)
P(sala) //申请店员
购买...
}
void salaer()
{
P(customer) //等待顾客
P(mutex_s) //申请叫号
count_s++; //叫号号码
V(mutex_s) //释放叫号资源
服务...
V(sala) //释放店员
}
睡眠的理发师问题
理发店里有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发
椅上睡觉。当一个顾客到来时,他必须先叫醒理发师,如果理发师正在理发时又有顾客来到,则如果有空
椅子可坐,他们就坐下来等;如果没有空椅子,他就离开。这里的问题是:为理发师和顾客各编写一段程
序,来描述他们行为。要求不能带有竞争条件。
用信号量和PV操作实现
睡眠的理发师
int chair =n //椅子数
int wait =0 // 等待者数
semaphore barber =1; //理发师状态
semaphore customer =0; //顾客数
semaphore mutex =1; //临界区
void barber()
{
while(1)
{
P(customer) //申请等待顾客
P(mutex) //申请临界区
wait--; //等待的顾客减一
V(barber) //理发师准备理发
V(mutex) //释放临界区
}
CUT(); //理发
}
void customer()
{
P(mutex) //申请临界区
if(wait<chair) //有空位置
{
wait++; //等待者加一
V(customer) //唤醒理发师
V(mutex) //释放临界
P(barber) //申请理发师,理发师空闲则理发,理发师忙等待
CUT(); //理发
}
else
V(mutex) //无位置,离开
}