吃水果问题
分析:
共享资源: 盘子是共享资源,需要互斥访问。
同步关系:
盘子空时,女儿和儿子不能取水果。
盘子满时,爸爸和妈妈不能放水果。
女儿只能等盘子里有苹果时才能取。
儿子只能等盘子里有香蕉时才能取。
爸爸放苹果后,应通知女儿(可能有苹果了)。
妈妈放香蕉后,应通知儿子(可能有香蕉了)。
女儿取走苹果后,应通知生产者(盘子有空位了)。
儿子取走香蕉后,应通知生产者(盘子有空位了)。
解决方案:
我们需要定义几个信号量:
mutex: 互斥信号量,用于保护对盘子的访问。初始值为 1。
empty: 同步信号量,表示盘子中可用的空位数。假设盘子最多能放 N 个水果,则初始值为 N。
apple: 同步信号量,表示盘子中苹果的数量。初始值为 0。
banana: 同步信号量,表示盘子中香蕉的数量。初始值为 0。
各个进程的伪代码描述:
// --- 信号量定义 ---
semaphore mutex = 1; // 互斥访问盘子
semaphore empty = N; // 盘子空位数,N为盘子容量
semaphore apple = 0; // 盘中苹果数
semaphore banana = 0; // 盘中香蕉数
// --- 爸爸进程 (生产者 - 苹果) ---
Process Father:
while (true) {
// 准备一个苹果
P(empty); // 等待盘子有空位 (获取空位资源)
P(mutex); // 进入临界区 (申请访问盘子)
// 将苹果放入盘子
V(mutex); // 退出临界区 (释放对盘子的访问)
V(apple); // 通知有苹果了 (苹果资源数+1)
}
// --- 妈妈进程 (生产者 - 香蕉) ---
Process Mother:
while (true) {
// 准备一个香蕉
P(empty); // 等待盘子有空位 (获取空位资源)
P(mutex); // 进入临界区 (申请访问盘子)
// 将香蕉放入盘子
V(mutex); // 退出临界区 (释放对盘子的访问)
V(banana); // 通知有香蕉了 (香蕉资源数+1)
}
// --- 女儿进程 (消费者 - 苹果) ---
Process Daughter:
while (true) {
P(apple); // 等待有苹果可吃 (获取苹果资源)
P(mutex); // 进入临界区 (申请访问盘子)
// 从盘子取出一个苹果
V(mutex); // 退出临界区 (释放对盘子的访问)
V(empty); // 通知盘子空位数+1 (释放空位资源)
// 吃掉苹果
}
// --- 儿子进程 (消费者 - 香蕉) ---
Process Son:
while (true) {
P(banana); // 等待有香蕉可吃 (获取香蕉资源)
P(mutex); // 进入临界区 (申请访问盘子)
// 从盘子取出一个香蕉
V(mutex); // 退出临界区 (释放对盘子的访问)
V(empty); // 通知盘子空位数+1 (释放空位资源)
// 吃掉香蕉
}