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

3.4 実験結果について

この節では、スレッドアナライザを使用して、食事する哲学者プログラムのデッドロックを調査する方法を説明します。最初に実デッドロックになる実行を検証し、そのあとで、正常終了するが、デッドロックの可能性がある実行を調べます。

3.4.1 デッドロックになる実行の検証

次のリストは、食事する哲学者プログラムが実デッドロックになる実行を示しています。

prompt% cc din_philo.c -mt -g             

prompt% collect -r deadlock a.out
実験データベース tha.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 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)

CTRL-C を押して実行を終了します


% er_print tha.1.er 
(er_print) deadlocks

デッドロック #1, 潜在的デッドロック
	スレッド #2
		ロック保持中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #3
		ロック保持中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #4
		ロック保持中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #5
		ロック保持中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #6
		ロック保持中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"

デッドロック #2, 実デッドロック
	スレッド #2
		ロック保持中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #3
		ロック保持中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #4
		ロック保持中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #5
		ロック保持中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #6
		ロック保持中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"

デッドロック一覧の概要: 実験: tha.1.er 総デッドロック数: 2
(er_print) 

次のスクリーンショットは、スレッドアナライザでのこのデッドロック情報を示しています。

スレッドアナライザのウィンドウに表示された実デッドロック情報のスクリーンショット

スレッドアナライザは、din_philo.c について 2 つのデッドロック (潜在的と実デッドロック 1 つずつ) を報告しています。よく見ると、2 つのデッドロックは同一であることがわかります。このデッドロックに関係している循環チェーンは次のようなものです。

スレッド 2: 

アドレス 0x215a8 でロック保持、 アドレス 0x215c0 でロック要求

スレッド 3: 

アドレス 0x215c0 でロック保持、アドレス 0x215d8 でロック要求

スレッド 4: 

アドレス 0x215d8 でロック保持、 アドレス 0x215f0 でロック要求

スレッド 5: 

アドレス 0x215f0 でロック保持、 アドレス 0x21608 でロック要求

スレッド 6: 

アドレス 0x21608 でロック保持、 アドレス 0x215a8 でロック要求

チェーンの最初のスレッド (スレッド #2) を選択し、「デュアルソース」タブをクリックして、スレッド #2 のロック保持が発生したアドレス 0x215a8 に対応するソースコード位置と、ロック要求が発生したアドレス 0x215c0 に対応するソースコード位置を確認します。次のスクリーンショットは、スレッド 2 の「デュアルソース」タブを示しています。デフォルトメトリック (「排他的デッドロック」メトリック) は各ソース行の左側に表示されます。このメトリックは、その行について、1 つのデッドロックに関係するロック保持またはロック要求動作が報告された回数を示します。

スレッドアナライザの「デュアルソース」タブのスクリーンショット - 潜在的デッドロックの例

3.4.2 デッドロックの可能性があるが正常終了する実行の検証

食事する哲学者プログラムは、十分なスリープ引数値を指定すると、実デッドロックを回避し、正常に終了することができます。ただし、正常終了は、プログラムがデッドロックにならないことを意味するわけではありません。単に、実行中に、保持および要求されたロックによってデッドロックチェーンが形成されなかっただけです。別の実行でタイミングが変われば、実デッドロックが発生する可能性があります。次のリストは、食事する哲学者プログラムが正常終了する実行を示しています。ただし、er_print ユーティリティーとスレッドアナライザからは潜在的デッドロックが報告されます。

% cc din_philo.c -mt -g                


% collect -r deadlock a.out 40
Creating experiment database tha.2.er ...
Philosopher 0 is done thinking and now ready to eat.
Philosopher 2 is done thinking and now ready to eat.
Philosopher 1 is done thinking and now ready to eat.
Philosopher 3 is done thinking and now ready to eat.
Philosopher 2: got right  chopstick 2
Philosopher 3: got right  chopstick 3
Philosopher 0: got right  chopstick 0
Philosopher 4 is done thinking and now ready to eat.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
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 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
...
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 3: got right  chopstick 3
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 4 is done eating.
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3 is done eating.
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0 is done 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.
%

実行は正常に終了します


% er_print tha.2.er 
(er_print) deadlocks

デッドロック #1, 潜在的デッドロック
	スレッド #2
		ロック保持中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #3
		ロック保持中:	0x215c0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #4
		ロック保持中:	0x215d8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #5
		ロック保持中:	0x215f0, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
	スレッド #6
		ロック保持中:	0x21608, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"
		ロック要求中:	0x215a8, 位置: grab_chopstick + 0x0000002C, 行 101 "din_philo.c"

デッドロック一覧の概要: 実験: tha.2.er 総デッドロック数: 1
(er_print) 
 

次のスクリーンショットは、スレッドアナライザインタフェースに表示された潜在的ロック情報を示しています。

スレッドアナライザウィンドウに表示された潜在的デッドロック情報のスクリーンショット