Skip to main content

「食事する哲学者」で学ぶデッドロック

最近 プログラミング言語Rustを読んでるのですが、並行処理のチュートリアルで「食事する哲学者」という問題を知りました。

昔々、裕福な慈善家が、5人の高名な哲学者が宿泊できるカレッジを寄付しました。それぞれの哲学者には思索活動にふさわしい部屋が与えられました; また共用のダイニングルームもあり、そこには丸いテーブルが置かれ、5人それぞれが専用で使うイス5脚で取り囲まれていました。 彼らはテーブルを反時計回りに座ります。哲学者の左側にはそれぞれ金のフォークが配され、 中央には大きなボウルに入ったスパゲッティが常に補充されていました。哲学者は大半の時間を思慮に費やすのですが; 空腹になった時は、ダイニングルームに出向き、自分専用のイスに座り、左側のフォークを取上げ、スパゲッティに突き刺します。 しかし、絡まり合ったスパゲッティを口元まで運ぶには2本目のフォークが必要でした。なので哲学者は自分の右側にあるフォークも使う必要がありました。 食べ終わったら両側のフォークを元に戻し、席から立ちあがって、思索活動を続けます。 もちろん、1本のフォークは同時に1人の哲学者しか使えません。他の哲学者が食事したければ、 フォークが再び戻されるまで待たねばなりません。

並行処理でデッドロックが起こりうる問題です。

f:id:sasa5740:20191127212423p:plain
丸が哲学者で棒がフォークです!!!!
そのまま各哲学者が同時に右のフォークをとるとこうなります

f:id:sasa5740:20191127212547p:plain
丸が哲学者で棒がフォークです!!!!!!!

この状態になってしまうと1が左のフォークを取りたくても5が持っているので取れない、5も早くパスタをとってフォークをおろしたいけど4がフォークを持っているので取れない。…となり全員がお互いのフォークを下ろすのをおみあいしてしまう、いわゆるデッドロック状態になります。

プログラミング言語Rustでは5だけ最初に左のフォークを取らせて確実に誰かが両手にフォークを持てる状況を強制させていました。
この問題は 食事する哲学者の問題 - Wikipediaにも乗ってるけど色々デッドロックを起こさない方法があります。

セマフォって概念ここで初めて知りました。 dirty/cleanなんかはページングで使われてる気がする。

Rustにセマフォあったみたいだけど非推奨になっていた。MutexとCondvarでなんとかするのだろうか。