クリティカルセクション

出典: フリー百科事典『ウィキペディア(Wikipedia)』
2013年3月14日 (木) 16:39時点におけるAddbot (トーク)による版 (ボット: 言語間リンク 17 件をウィキデータ上の d:q1046373 に転記)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

クリティカルセクション(Critical section)とは、計算機上において、単一のリソースに対して、複数の処理が同時期に実行されると、破綻をきたす部分を指す。クリティカルセクションにおいては、排他制御を行うなどしてアトミック性を確保する必要がある。

リソースの同一性が保証されなくなる可能性がある場合は、クリティカルセクションでは常に排他制御を行う必要がある。

クリティカルセクションの排他制御ではデッドロックに注意する必要がある。

ウェブページの来訪者数を表すカウンタのプログラムを例にとって説明する。カウンターのプログラムはおおまかに次の処理からなる。

  1. ディスク等の記憶装置から現在のカウンタの値を読み出す
  2. カウンタの値を1増やす
  3. カウンタの値を記憶装置に書き戻す

実際はこの命令それぞれが複数の細かい命令からなるのが普通だ。

排他制御を使用しない場合

ここで、現在ディスクに書き込まれているカウンタの値が100だったとする。 ユーザーAがこのウェブページを訪れ、カウンタプログラムのスレッドAが実行しはじめたとしよう。スレッドAは1でカウンタの値を読み出し(値は100)、2で値を増やす(値は101)。次に3で値を書き戻すのだが、ここでユーザーBがウェブページを訪れたことによる別のスレッドBが実行され、すぐさまコンテキストスイッチが起きて処理がスレッドBに移されたとする。スレッドBがカウンタの値を読み出すと値は100になる。何故ならば、スレッドAがまだ3の処理を行っていないため、ディスク上の値は変化していないからである。そして、スレッドBは値を増やし、その結果の101という値をディスクに書き込み、スレッドを終了する。 次に再びスレッドAへ処理がうつり、スレッドAは3の処理を行い、ディスクには101という値が書き込まれて、スレッドAも処理を終える。

結果として、ユーザーAとユーザーBの2人がページを訪れたので、カウンタの値は2増えて102にならなければならないのに、結果としてディスクに書き込まれる値は101となる。

以上の処理を時間に沿ってまとめたものが以下の表である。

ディスク上の値 スレッドA(値) スレッドB(値)
100 スレッド発生
100 処理1(100)
100 処理2(101)
100 待機 スレッド発生
100 処理1(100)
100 処理2(101)
101 処理3(101)
101 スレッド終了
101 処理3(101)
101 スレッド終了

排他制御を使用した場合

排他制御をしたクリティカルセクションとは、1つのスレッドのみが使用権を得ることができるプログラム上の処理領域である。

あるスレッドが排他制御をしたクリティカルセクションに入っている間は、別のスレッドはクリティカルセクションに入ることができない。普通はそのスレッドは待機状態になる。

このカウンタプログラムの場合、プログラムの最初、つまり上の場合でいうと処理1の前に排他制御をしてクリティカルセクションに入るという処理を付け加える必要がある。そして、スレッドが終了する前に排他制御を解放してクリティカルセクションから出るという処理を付け加えれば完了だ。

ここで、先ほどと同様にスレッドAが処理1、処理2を終わらせて処理3を実行する前に、スレッドBが発生したとする。しかし、ここで既にスレッドAがクリティカルセクションに入っているため、スレッドBは処理を開始できないため待機状態となる。そしてスレッドAが処理を終え、クリティカルセクションから出るとスレッドBが再開する。結果として、意図したとおりの正しい動作になる。

以上の処理を時間に沿ってまとめたものが以下の表である。なおクリティカルセクションはCSと略している。

ディスク上の値 スレッドA(値) スレッドB(値) CSの所有者
100 スレッド発生
100 CSに入る スレッドA
100 処理1(100)
100 処理2(101)
100 待機 スレッド発生
100 CSへ入ることに失敗
101 処理3(101) 待機
101 CSから出て、スレッド終了
101 CSに入る スレッドB
101 処理1(101)
101 処理2(102)
102 処理3(102)
102 CSから出て、スレッド終了

関連項目

テンプレート:Asbox