Sun Studio 12: スレッドアナライザユーザーズガイド

3.2.2 哲学者 1 のスリープ時間の導入

潜在的デッドロックに対して考えられる 1 つの解決策は、哲学者 1 が時間を置いてから箸を取るようにすることです。コード面から言うと、箸を取ろうとする前に、指定した時間 (sleep_seconds)、 哲学者 1 をスリープさせることができます。このスリープが十分に長ければ、プログラムは実デッドロックなしに終了する可能性があります。実行可能ファイルの引数としてスリープする秒数を指定できます。引数を指定しなかった場合、哲学者はスリープしません。

次の擬似コードは、各哲学者のロジックを示しています。

   while (テーブルにはまだ食事がある)
      {
        if (スリープのための引数が指定されていて、自身は哲学者 1 である)
           {
             指定された時間スリープする
           }

        右の箸を持つ
        左の箸を持つ
        食事をする
        左の箸を置く
        右の箸を置く 
      }

次のリストは、哲学者 1 が 30 秒経過してから自分の箸を取るようなプログラムの実行を示しています。プログラムは最後まで実行され、5 人の哲学者全員が食事を終えます。

% a.out 30
Philosopher 0 is done thinking and now ready to eat.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 4 is done thinking and now ready to eat.
Philosopher 4: got right  chopstick 4
Philosopher 3 is done thinking and now ready to eat.
Philosopher 3: got right  chopstick 3
Philosopher 0: eating.
Philosopher 2 is done thinking and now ready to eat.
Philosopher 2: got right  chopstick 2
Philosopher 1 is done thinking and now ready to eat.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
...
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0 is done eating.
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 4 is done eating.
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 3 is done eating.
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 2 is done eating.
Philosopher 1: got right  chopstick 1
Philosopher 1: got left chopstick 2
Philosopher 1: eating.
Philosopher 1 is done eating.
%

実行は正常に終了します

スリープ引数の値を変更しながら、何回かプログラムを実行してみます。哲学者 1 がほんの短い時間で箸を取ろうとした場合はどうなりますか。また、もっと長い時間待つようにした場合はどうですか。実行可能ファイル a.out のスリープ引数の値を変更してみてください。スリープ引数あり、またはスリープ引数なしで、何回かプログラムを実行します。プログラムの実行が滞ることがありますが、最後まで実行されることもあります。プログラムの実行が滞るかどうかは、スレッドのスケジューリングと、スレッドによるロックの要求のタイミングによって異なります。