代码GitHub链接:https://github.com/tigmfg/PDProblem_csharp
实现哲学家进餐
class PDproblem
{
/当哲学家同时拿起左右两边的筷子时,才会开始进餐,防止进程死锁
public static readonly int maxPhilosopher = 5; // 最大的哲学家数量
public List<Semaphore> forks = new List<Semaphore>(); //用列表储存五个叉子
static Semaphore andSem = new Semaphore(1,1); //and信号量,当同时获得两个叉子时才能进餐
public void CreatForks()
{
for (int i = 0; i < maxPhilosopher; i++) //创建五个叉子信号量
{
forks.Add(new Semaphore(1, 1));
}
}
public void Dine(object numberObj)
{
while (true)
{
int number = Convert.ToInt32(numberObj) - 1; //列表索引从0开始,所以要-1
andSem.WaitOne(); //等待and信号量
forks[number].WaitOne(); //取得左侧叉子
Console.WriteLine(Thread.CurrentThread.Name + "取得左侧叉子");
forks[(number + 1) % maxPhilosopher].WaitOne(); //取得右侧叉子
Console.WriteLine(Thread.CurrentThread.Name + "取得右侧叉子");
Console.WriteLine(Thread.CurrentThread.Name + "开始进食");
andSem.Release(); //当同时获得两侧叉子时,释放and信号量
Thread.Sleep(1000);
forks[number].Release();
forks[(number + 1) % maxPhilosopher].Release(); //进餐结束,放下两个叉子
Console.WriteLine(Thread.CurrentThread.Name + "放下叉子,陷入思考");
Thread.Sleep(new Random().Next(2000, 5000));
}
}
}
实例化
class Program
{
static void Main(string[] args)
{
PDproblem table = new PDproblem(); //实例化解决方案
new Thread(new ThreadStart(table.CreatForks)).Start(); //先执行CreatForks,往叉子列表添加五个叉子信号量
Thread.Sleep(10);
Thread philosopher1 = new Thread(table.Dine); //创建线程
philosopher1.Name = "哲学家1";
Thread philosopher2 = new Thread(table.Dine);
philosopher2.Name = "哲学家2";
Thread philosopher3 = new Thread(table.Dine);
philosopher3.Name = "哲学家3";
Thread philosopher4 = new Thread(table.Dine);
philosopher4.Name = "哲学家4";
Thread philosopher5 = new Thread(table.Dine);
philosopher5.Name = "哲学家5";
philosopher1.Start(1); //引入参数,启用线程
philosopher2.Start(2);
philosopher3.Start(3);
philosopher4.Start(4);
philosopher5.Start(5);
philosopher1.Join();
philosopher2.Join();
philosopher3.Join();
philosopher4.Join();
philosopher5.Join();
}
}