JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.3: スレッドアナライザユーザーズガイド     Oracle Solaris Studio 12.3 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  スレッドアナライザとその機能について

2.  データの競合チュートリアル

3.  デッドロックのチュートリアル

3.1 デッドロックについて

3.2 デッドロックチュートリアルのソースファイルの入手

3.2.1 din_philo.c のソースコードリスト

3.3 食事する哲学者の問題

3.3.1 哲学者がデッドロックに陥るしくみ

3.3.2 哲学者 1 の休眠時間の導入

3.4 スレッドアナライザを使用したデッドロックの検索方法

3.4.1 ソースコードをコンパイルする

3.4.2 デッドロック検出実験を作成する

3.4.3 デッドロック検出実験を検証する

3.4.3.1 スレッドアナライザを使用したデッドロック検出実験結果の表示

3.4.3.2 er_print を使用した、デッドロック検出実験結果の表示

3.5 デッドロックの実験結果について

3.5.1 デッドロックが発生した実行の検証

3.5.2 潜在的デッドロックがあるにもかかわらず完了した実行の検証

3.6 デッドロックの修正と誤検知について

3.6.1 トークンを使用した哲学者の規制

3.6.1.1 誤検知レポート

3.6.2 トークンの代替システム

A.  スレッドアナライザで認識される API

B.  役に立つヒント

3.5 デッドロックの実験結果について

この節では、スレッドアナライザを使用して、食事する哲学者のプログラムでのデッドロックを調べる方法について説明します。

3.5.1 デッドロックが発生した実行の検証

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

% 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:        0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #3
    Lock being held:        0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #4
    Lock being held:        0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #5
    Lock being held:        0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #6
    Lock being held:        0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"

Deadlock #2, Actual deadlock
  Thread #2
    Lock being held:        0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #3
    Lock being held:        0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #4
    Lock being held:        0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #5
    Lock being held:        0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #6
    Lock being held:        0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested:   0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"

Deadlocks List Summary: Experiment: din_philo.1.er Total Deadlocks: 2
(er_print)

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

図 3-2 din_philo.c で検出されたデッドロック

image:実デッドロックを表示したスレッドアナライザのウィンドウのスクリーンショット。

スレッドアナライザは、din_philo.c の 2 つのデッドロックを報告します (1 つは潜在的デッドロック、もう 1 つは実デッドロック)。より詳しく調べると、2 つのデッドロックは同一であるとわかります。

デッドロックに関する巡回チェーンは次のとおりです。

スレッド 2: アドレス 0x215a0 でロックを保持し、アドレス 0x215b8 でロックを要求
スレッド 3: アドレス 0x215b8 でロックを保持し、アドレス 0x215d0 でロックを要求
スレッド 4: アドレス 0x215d0 でロックを保持し、アドレス 0x215e8 でロックを要求
スレッド 5: アドレス 0x215e8 でロックを保持し、アドレス 0x21600 でロックを要求
スレッド 6: アドレス 0x21600 でロックを保持して、アドレス 0x215a0 でロックを要求

チェーン内の最初のスレッド (スレッド #2) を選択し、続いて「デュアルソース」タブをクリックすると、スレッド #2 がアドレス 0x215a0 でロックを取得したソースコード内の位置と、アドレス 0x215b8 でロックを要求したソースコード内の位置が表示されます。

次のスクリーンショットには、スレッド #2 の「デュアルソース」タブが示されています。スクリーンショットの上半分には、スレッド #2 が行 106 で pthread_mutex_lock() を呼び出すことによって、アドレス 0x215a0 でロックを取得したことが表示されています。スクリーンショットの下半分には、同じスレッドが行 106 で pthread_mutex_lock() を呼び出すことによって、アドレス 0x215b8 でロックを要求したことが表示されています。pthread_mutex_lock() への 2 つの呼び出しは、それぞれ別のロックを引数として使用しています。一般的に、ロック取得オペレーションとロック要求オペレーションは同じソース行に存在できません。

デフォルトのメトリック (排他的デッドロックメトリック) がスクリーンショットの各ソース行の左側に表示されます。このメトリックは、デッドロックに関与したロック取得またはロック要求オペレーションが、そのソース行で報告された回数を示します。デッドロックチェーンの一部となるソース行のみが、このメトリックについて 0 より大きい値を持ちます。

図 3-3 din_philo.c での潜在的デッドロック

image:潜在的デッドロックを示すスレッドアナライザの「デュアルソース」タブのスクリーンショット。

3.5.2 潜在的デッドロックがあるにもかかわらず完了した実行の検証

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

% cc -g -o din_philo_pt din_philo.c
% collect -r deadlock -o din_philo_pt.1.er din_philo_pt 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 left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 2: got left chopstick 3
Philosopher 2: 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.
%

Execution terminated normally

太字で示された次のコマンドを入力して、er_print ユーティリティーで実験結果を検証します。

% er_print din_philo_pt.1.er
(er_print) deadlocks
Deadlock #1, Potential deadlock
  Thread #2
    Lock being held:      0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #3
    Lock being held:      0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #4
    Lock being held:      0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #5
    Lock being held:      0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
  Thread #6
    Lock being held:      0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"
    Lock being requested: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c"

Deadlocks List Summary: Experiment: din_philo_pt.1.er Total Deadlocks: 1
(er_print)

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

図 3-4 din_philo.c での潜在的デッドロック

image:潜在的デッドロックを表示したスレッドアナライザのスクリーンショット。