【くりてぃかるせくしょん】

クリティカルセクション とは?

💡 線路の単線区間――すれ違いできないから1列車ずつ通す!
📌 このページのポイント
クリティカルセクションの構造 スレッドA スレッドB 通常処理 lock() クリティカル セクション unlock() 通常処理 通常処理 ロック待ち(ブロック) lock() クリティカル セクション 解放 共有リソース 同時アクセス禁止 保護区間 ロック操作 待機中
クリティカルセクションのイメージ
ひよこ ひよこ

クリティカルセクションって何のこと?

ペンギン先生 ペンギン先生

プログラムの中で「ここは同時に2つ以上のスレッドが実行したらマズい」という区間のことだよ。線路の単線区間をイメージしてみて。すれ違いができないから、1本の列車が通り過ぎるまで次の列車は待つよね

ひよこ ひよこ

どうして同時に実行するとマズいの?

ペンギン先生 ペンギン先生

例えばカウンターを+1する処理を考えてみて。「値を読む→+1する→書き戻す」の3ステップの途中で別のスレッドが割り込むと、片方の更新が消えちゃうんだ。これがレースコンディションだよ

ひよこ ひよこ

どうやって保護するの?

ペンギン先生 ペンギン先生

クリティカルセクションの前でロック(ミューテックスなど)を取得して、終わったら解放するんだ。擬似コードだとこんな感じだよ。lock()→共有データの操作→unlock()。この間は他のスレッドがロックを取得できないから安全に操作できるんだ

ひよこ ひよこ

クリティカルセクションは長くても短くても同じなの?

ペンギン先生 ペンギン先生

短いほうが断然いいよ!ロックしている間は他のスレッドが全部待たされるから、長いクリティカルセクションは性能のボトルネックになるんだ。必要最小限の操作だけをロックの中に入れるのが鉄則だよ

ひよこ ひよこ

Windowsにも「クリティカルセクション」ってAPIがあるって聞いたけど…

ペンギン先生 ペンギン先生

いい質問だね!Windows APIのCRITICAL_SECTIONは、同一プロセス内で使える軽量なミューテックスのようなものだよ。カーネルを経由しないぶん高速なんだ。Linuxだとpthread_mutexが同じ役割を担っているよ

ひよこ ひよこ

クリティカルセクションを設計するときのコツってある?

ペンギン先生 ペンギン先生

3つ覚えておくといいよ。1つ目は「区間をできるだけ短くする」こと。2つ目は「ロックの中でI/Oや時間のかかる処理をしない」こと。3つ目は「ロックの入れ子を避ける」こと。入れ子にするとデッドロックのリスクが急上昇するからね

ひよこ ひよこ

並行プログラミングって奥が深いんだね!

ペンギン先生 ペンギン先生

そうだね。でもクリティカルセクションの概念は並行プログラミングの一番の基本だから、ここをしっかり押さえておけば他の同期機構も理解しやすくなるよ

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
クリティカルセクションって出てきたら「同時に実行すると壊れるから1スレッドだけに制限するコード区間」と思えばだいたいOK!
📖 おまけ:英語の意味
「Critical Section」 = 危険区間・臨界区間
💬 Critical(重大な・危険な)+ Section(区間)で「慎重に扱わないと危険なコードの区間」という意味だよ
← 用語集にもどる