Leetcode concurrency #1226 The Dining Philosophers (in golang)

Chunting Wu
Mar 30, 2021

--

這是concurrency的最後一篇,前面已經試過幾種常見的同步模式,這次要解的題目是經典的哲學家問題,但處理的手法應該已經被很多教科書討論過了,不外乎引入服務生、搶到叉子就吃搶不到就等,和比較近期的用餐券換叉子。

這麼經典的問題教科書應該都有寫過我就大略描述下就好。總之,五個哲學家坐在同一張圓桌,每個人都有一碗吃不完的麵,但只有五支叉子放在人與人之間,要吃麵就一定要用兩支叉子,沒有兩支叉子就發呆。這裡有個變體,要接收一個整數,代表每個人至少要吃過幾次,例如:n=1,表示每個人都至少吃過一次就散會。

解法也很簡單,我選用最單純的搶叉子,每支叉子按順時鐘順序編號,每個人都要先拿編號小的才能拿編號大的,但放叉子要從編號大的先放,才能放小的。

每個叉子都是一個互斥鎖,小的先鎖再鎖大的,大的先解鎖才解小的。唯一要注意的一點是,吃完以後要看一下是不是每個人都吃過了,如果大家都吃過就準備結束散會;一定要在吃完的時候就看,因為這時候才是在critical section內,過了就要再搶一次,那沒必要。

有趣的一點是,我在Leetcode的playground跑這段code,會發現有些哲學家餓到不行,會狂搶叉子,導致結束的時候某人大概續了幾千次麵,真是個大胃王。

--

--

Chunting Wu
Chunting Wu

Written by Chunting Wu

Architect at SHOPLINE. Experienced in system design, backend development, and data engineering.

No responses yet