独木桥问题——读写问题变形
有一座东西方向的独木桥,请分别用PV操作实现以下3个要求:
- 每次只允许一个人过桥;
- 当独木桥上有行人时,同方向的行人可以同时过桥,相反方向的人必须等待;
- 当独木桥上有自东向西的行人时,同方向的行人可以同时过桥,从西向东的方向只允许一个人单独过桥;
是读者写者问题的变形
(1)使用mutex互斥信号量控制对共享资源桥的访问,信号量初始值为1,以两个进程分别来表示不同的过桥方向
semaphore mutex = 1;
Process EastToWest()
{
while(1)
{
P(mutex);
eastToWest; // 东到西过桥
V(mutex);
}
}
Process WestToEast()
{
while(1)
{
P(mutex);
westToEast; // 西到东过桥
V(mutex);
}
}
(2)使用互斥mutex信号量控制对桥的访问,使用whetherY来控制同向访问信号量,使用whetherN来控制反向信号量,这三个信号量的初始值都应该未1。使用进程Yes()来模拟与桥上行人同向过桥行为,进程No()来模拟桥上人过桥方向相反的过桥行为,代码如下:
// 桥上有人,同方向同时过桥,反向等待
int n1=n2=0;
int count1 = n1; // 同向行人计数
int count2 = n2; // 反向行人计数
semaphore mutex = 1; // 互斥访问桥
semaphore whetherY= 1; // 同向互斥信号量,保证count1
semaphore whetherN= 1; // 反向互斥信号量,保证count2
//同向
Process Yes()
{
while(1)
{
P(mutex);
P(whetherY);
count1++;
if(count1==1)
P(mutex);
V(whetherY);
count1PeopleCrossBridge; // 同向过桥
P(whetherY);
count1--;
if(count1==0)
V(mutex);
V(whetherY);
}
}
//反向
Process No()
{
while(1)
{
P(whetherN);
count2++;
if(count2==1)
P(mutex);
V(whetherN);
count2PeopleCrossBridge; // 反向过桥
P(whetherN);
count2--;
if(count2==0)
V(mutex);
V(whetherN);
}
}
(3)使用互斥信号量mutex控制对桥的互斥访问,使用whether信号量来控制是否是自东向西的信号量,使用count来计数自东向西的过桥人数。
// 当独木桥上有自东向西的行人时,同方向的行人可以同时过桥,
// 从西向东的方向只允许一个人单独过桥
int count = 0; // 计数器
semaphore mutex = 1; // 互斥信号量
semaphore weatehr = 1;
Process EastToWest()
{
while(1)
{
P(whether);
count++;
if(count==1)
P(mutex);
V(whether);
CrossBridge;
P(whether)
count--;
if(count==0)
V(mutex);
V(whether);
}
}
Process WestToEast()
{
while(1)
{
P(mutex);
CrossBridge;
V(mutex);
}
}