1.题目:桌上有一个能盛得下五个水果的空盘子。爸爸不停的向盘子中放苹果或者桔子,儿子不停的从盘子中取出桔子享用,女儿不停的从盘中取出苹果享用。规定三人不能同时使用盘子。试用信号量实现爸爸、儿子、女儿这三个循环进程之间的同步。
代码如下:
//苹果,橘子,盘子是临界资源
semaphore mutex = 1, plate = 5, apple = 0, orange = 0;
void father()
{
while (true)
{
buy fruits;
wait(plate);
wait(mutex);
put in a fruit;
signal(mutex);
if (fruit == apple)
signal(apple);
else
signal(orange);
}
}
void boy()
{
wait(orange);
wait(mutex);
put out and eat an orange;
signal(mutex);
signal(plate);
}
void girl()
{
wait(apple);
wait(mutex);
put out and eat an apple;
signal(mutex);
signal(plate);
}
2.题目:试利用记录型信号量写出一个,至多只有四位哲学家去拿左边的筷子,不会死锁的哲学家进餐问题的算法。
代码如下:
semaphore chopstick[5] = {1, 1, 1, 1, 1};
semaphore mutex = 4;
void philosopher_i()
{
while (true)
{
wait(mutex);
wait(chopstick[i]);
wait(chopstick[(i + 1) % 5]);
eating;
signal(chopstick[i]);
signal(chopstick[(i + 1) % 5]);
wait(mutex);
thinking;
}
}
3.题目:请用信号量解决以下的“过独木桥”问题:同一方向的行人可连续过桥,当某一方向有人过桥时,另一方向的行人必须等待;当某一方向无人过桥时,另一方向的行人可以过桥。
代码如下
// 实现左右两边过桥方向的互斥访问,上下桥属于临界资源,需要互斥访问
int left = 0, right = 0; //分别表示左边和右边过桥的人数
semaphore mutex = 1,S_l=1,S_R=1; //S_l ,S_r 为对临界资源left和right的互斥访问
void left()
{
while (true)
{
wait(S_l); //临界资源互斥访问
if (left == 0) //左边开始有人过
wait(mutex);
left = left + 1;
signal(S_l);
cross the bridge;
wait(S_l);
left = left - 1;
if (left == 0) //左边所有人都过完
signal(mutex);
signal(S_l);
}
}
void right()
{
wait(S_r); //临界资源互斥访问
if (right == 0) //右边开始有人过
wait(mutex);
right = right + 1;
signal(S_r);
cross the bridge;
wait(S_r);
right = right - 1;
if (right == 0) //右边所有人都过完
signal(mutex);
signal(S_r);
}
}
4.题目:嗜睡的理发师问题:一个理发店由一个有N张沙发的等候室和一个放有一张理发椅的理发室组成。没有顾客要理发时,理发师便去睡觉。当一个顾客走进理发店时,如果所有的沙发都已经被占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。在理发完成后,顾客必须付费,直到理发师收费后才能离开理发店。试用信号量实现这一同步问题。
代码如下:
// 理发师问题
// 临界资源:barber_sofa:理发椅,sofa_ed_num:被占用的沙发的数量,costumer:顾客数量
// mutex实现customer_num的互斥访问;
// 收付款也是影响程序能否向下进行的互斥量:
semaphore mutex = 1, barber_sofa = 1;
semaphore pay = 0,receive = 0;
int sofa_ed_num = 0; //被占用的沙发数量
void customer()
{
come in; //进店
wait(mutex) //对临界资源sofa_ed_num的互斥访问
if (sofa_ed_num >= N)
{
leave; //沙发全被占用,离开理发店
signal(mutex); //customer_num 互斥访问结束
}
else
{
sofa_ed_num++; //沙发没有被全部占用,坐到沙发上
signal(mutex); //customer_num 互斥访问结束
wait(barber_sofa); //等待理发椅空出
wait(mutex); //对临界资源sofa_ed_num的互斥访问
sofa_ed_num--; //顾客离开沙发
signal(mutex); //customer_num 互斥访问结束
signal(customer); //顾客到来,唤醒理发师
hair cut; //剪发
signal(pay); //顾客付款
wait(receive); //等待理发师收款
siganl(barber_sofa); //顾客让出理发椅
leave; //离开
}
}
void barber()
{
while (true)
{
wait(customer); //当customer=0时,等待顾客到来,同时睡觉
//customer 不为0,则执行如下操作
harcuting; //理发
wait(pay); //等待顾客付款
signal(receive); //理发师收款
}
}