第4章 同步控制 Synchronization ---哲学家进餐问题(The Dining Philosophers)
哲学家进餐问题是这样子的:好几位哲学家围绕着餐桌坐,每一位哲学家要么思考,要么等待,要么就吃饭。为了吃饭,哲学家必须拿起两支筷子(分放于左右两端)。不幸的是,筷子的数量和哲学家相等,所以每支筷子必须由两位哲学家共享。图4-1 显现出这种状态。? FAQ 16:我如何避免死锁?
哲学家都是有点倔强的人,他们不愿意在吃完之前放下他们的筷子。因此,如果每位哲学家都抓住了左手边的筷子,他们就不可能抓到右手边的筷子,因为右边的哲学家正在使用那支筷子,而且拒绝出让。
在 SwapLists() 中所发生的死锁问题,是因为它必须等待两个critical section。哲学家的死锁问题则是因为他们都必须等待两支筷子。在程序之中我们必须要求操作系统给我们一点帮助,如critical sections 或其他什么东西。不幸的是,critical sections 没办法使用于这种情况。
这个问题也可以这样解决:使用一个 critical section 并允许一次只能够有一位哲学家拿起或放下筷子。这并不是最好的解决方法,因为它限制了哲学家的自由意志,同时也让他们做了非必要的等待。
还记得上一章最后提到的 WaitForMultipleObjects() 函数吗?它允许你对操作系统发出“等待”的要求,直到所有指定的对象都激发才返回。同一时我能够等待一个以上的critical sections 吗?刻取得两支筷子而非一支筷子,是本案的关键。但是 WaitForMultipleObjects()等待的只是核心对象,critical section 并不是核心对象(它没有 handle)。因此,我们必须寻求另一种 Win32 同步机制:mutex。