次のリストには、実デッドロックになった食事する哲学者のプログラムの実行が示されています。
% cc -g -o din_philo din_philo.c % collect -r deadlock -o din_philo.1.er din_philo Creating experiment database din_philo.1.er ... Philosopher 1 is done thinking and now ready to eat. Philosopher 2 is done thinking and now ready to eat. Philosopher 3 is done thinking and now ready to eat. Philosopher 0 is done thinking and now ready to eat. Philosopher 1: got right chopstick 1 Philosopher 3: got right chopstick 3 Philosopher 0: got right chopstick 0 Philosopher 1: got left chopstick 2 Philosopher 3: got left chopstick 4 Philosopher 4 is done thinking and now ready to eat. Philosopher 1: eating. Philosopher 3: eating. Philosopher 3: got right chopstick 3 Philosopher 4: got right chopstick 4 Philosopher 2: got right chopstick 2 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 1: got right chopstick 1 Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 0: got right chopstick 0 Philosopher 3: got left chopstick 4 Philosopher 3: eating. Philosopher 4: got right chopstick 4 Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 3: got right chopstick 3 Philosopher 1: got left chopstick 2 Philosopher 1: eating. Philosopher 2: got right chopstick 2 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 1: got right chopstick 1 Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 0: got right chopstick 0 Philosopher 3: got left chopstick 4 Philosopher 3: eating. ... Philosopher 4: got right chopstick 4 Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 2: got right chopstick 2 Philosopher 3: got right chopstick 3 (hang) Execution terminated by pressing CTRL-C
次のコマンドを入力して、er_print ユーティリティーで実験結果を検証します。
% er_print din_philo.1.er (er_print) deadlocks
Deadlock #1, Potential deadlock Thread #2 Lock being held: 0x21380, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x21398, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #3 Lock being held: 0x21398, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213b0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #4 Lock being held: 0x213b0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213c8, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #5 Lock being held: 0x213c8, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213e0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #6 Lock being held: 0x213e0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x21380, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Deadlock #2, Actual deadlock Thread #2 Lock being held: 0x21380, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x21398, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #3 Lock being held: 0x21398, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213b0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #4 Lock being held: 0x213b0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213c8, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #5 Lock being held: 0x213c8, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x213e0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Thread #6 Lock being held: 0x213e0, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c" Lock being requested: 0x21380, at: grab_chopstick + 0x00000024, line 105 in "din_philo.c"
次のスクリーンショットは、スレッドアナライザで表示されたデッドロック情報を示します。
図 3-2 din_philo.c で検出されたデッドロック
スレッドアナライザは、din_philo.c の、潜在的デッドロックと実デッドロックの 2 つのデッドロックを報告します。より詳しく調べると、2 つのデッドロックは同一であるとわかります。
デッドロックに関する巡回チェーンは次のとおりです。
|
チェーン内の最初のスレッド (スレッド #2) を選択してから「デュアルソース」ビューをクリックすると、スレッド #2 がアドレス 0x21380 でロックを取得したソースコード内の位置と、アドレス 0x21398 でロックを要求したソースコード内の位置が表示されます。
次のスクリーンショットには、スレッド #2 の「デュアルソース」ビューが示されています。スクリーンショットの上半分には、スレッド #2 が行 105 で pthread_mutex_lock() を呼び出すことによって、アドレス 0x21380 でロックを取得したことが表示されています。スクリーンショットの下半分には、同じスレッドが行 105 で pthread_mutex_lock() を呼び出すことによって、アドレス 0x21398 でロックを要求したことが表示されています。pthread_mutex_lock() への 2 つの呼び出しは、それぞれ別のロックを引数として使用しています。一般的に、ロック取得オペレーションとロック要求オペレーションは同じソース行に存在できません。
デフォルトのメトリック (排他的デッドロックメトリック) がスクリーンショットの各ソース行の左側に表示されます。このメトリックは、デッドロックに関与したロック取得またはロック要求オペレーションが、そのソース行で報告された回数を示します。デッドロックチェーンの一部となるソース行のみが、このメトリックについて 0 より大きい値を持ちます。
図 3-3 din_philo.c での潜在的デッドロック