苹果-桔子问题是操作系统中P、V操作部分经典的问题,属于复杂一点的生产者-消费者问题,可以抽象的理解为两个生产者和两个消费者被连接到大小为1的缓冲区上。
#实现语言:C#
#问题描述:
桌子上有一只盘子,每次只能向其中放入一个水果,要求:
1、爸爸专向盘子里放苹果,女儿专等吃盘子中的苹果;
2、妈妈专向盘子里放桔子,儿子专等吃盘子中的桔子;
3、只有盘子为空时,爸爸或妈妈就可向盘子中放入一个水果;
4、仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。
#问题分析:
首先4个进程对盘子的操作是互斥的,
而爸爸和女儿,妈妈和儿子之间又是同步关系,
所以需要设置两个同步信号量,一个互斥信号量;
using System;
using System.Threading;
namespace ConsoleApp3
{
class Program
{
// 定义三个信号量:apple,orange为同步信号量;planet为互斥信号量
private static Semaphore apple, orange, planet;
static void Main(string[] args)
{
// 对信号量初始化
apple = new Semaphore(0, 1); // 盘子里没有苹果,同步信号量
orange = new Semaphore(0, 1); // 盘子里没有桔子,同步信号量
planet = new Semaphore(1, 1); // 互斥信号量,盘子里只允许放一个水果
// 定义四个进程
Thread Father = new Thread(father);
Thread Mother = new Thread(mother);
Thread Son = new Thread(son);
Thread Daughter = new Thread(daughter);
// 启动进程
Father.Start();
Mother.Start();
Son.Start();
Daughter.Start();
}
protected static void father()
{
while(true)
{
planet.WaitOne(); // P(planet)
Console.WriteLine("爸爸向盘子里放入一个苹果");
Thread.Sleep(2000);
apple.Release(); // V(apple)
}
}
protected static void mother()
{
while (true)
{
planet.WaitOne(); // P(planet)
Console.WriteLine("妈妈向盘子里放一个桔子");
Thread.Sleep(2000);
orange.Release(); // V(orange)
}
}
protected static void daughter()
{
while (true)
{
apple.WaitOne(); // P(apple)
Console.WriteLine("女儿从盘子里取出一个苹果");
Thread.Sleep(2000);
planet.Release(); // V(planet)
Console.WriteLine("女儿吃掉苹果");
}
}
protected static void son()
{
while (true)
{
orange.WaitOne(); // P(orange)
Console.WriteLine("儿子从盘子里取出一个桔子");
Thread.Sleep(2000);
planet.Release(); // V(planet)
Console.WriteLine("儿子吃掉桔子");
}
}
}
}
运行结果如下: