クリティカルセクション (クリティカルセクション) とは | 意味や読み方など丁寧でわかりやすい用語解説

作成日: 更新日:

クリティカルセクション (クリティカルセクション) の読み方

日本語表記

クリティカルセクション (クリティカルセクション)

英語表記

critical section (クリティカルセクション)

クリティカルセクション (クリティカルセクション) の意味や用語解説

クリティカルセクションとは、複数のプロセスやスレッドが同時に実行すると、予期せぬ問題を引き起こす可能性があるプログラムコードの一部分を指す。特に、複数の処理単位が並行して動作するマルチタスク環境やマルチスレッド環境において、データの整合性を保つために極めて重要な概念である。ここでいう問題とは、共有リソースへのアクセスが原因で発生する競合状態を指す。共有リソースとは、メモリ上の変数、ファイル、データベースのレコード、あるいはプリンターのようなハードウェアデバイスなど、複数のプロセスやスレッドからアクセスされる可能性のある対象全般を意味する。もし、このような共有リソースを操作するコード部分(クリティカルセクション)が何の保護もなしに同時に実行されると、データが破壊されたり、処理結果が実行のタイミングによって変わってしまったりする不整合が生じる。したがって、クリティカルセクションは、一度に一つのプロセスあるいはスレッドだけが実行できるように保証されなければならない。この仕組みを排他制御と呼ぶ。クリティカルセクションを適切に定義し、排他制御を施すことは、信頼性の高い並行処理システムを構築するための基本的な要件である。 クリティカルセクションの必要性を理解するためには、競合状態(Race Condition)という現象を知ることが不可欠である。競合状態とは、複数のスレッドなどが共有リソースにアクセスし、その処理の実行順序が結果に影響を与えてしまう状況のことだ。例えば、ある共有変数カウンターの値をインクリメント(1加算)する処理を考える。この処理は、内部的には「変数の現在の値を読み込む」「読み込んだ値に1を加算する」「結果を元の変数に書き戻す」という複数のステップで構成される。スレッドAがこの処理を実行中に、OSのスケジューリングによって一時停止し、スレッドBに処理が切り替わったと仮定する。スレッドAがカウンターの値(例えば10)を読み込んだ直後に停止し、次にスレッドBが同じカウンターの値(まだ更新されていない10)を読み込む。その後、スレッドBが計算(10+1=11)を行い、結果の11をカウンターに書き戻す。そして再びスレッドAに処理が戻ると、Aは停止前に読み込んでいた10を元に計算(10+1=11)を行い、結果の11をカウンターに書き戻す。この結果、2回のインクリメント処理が実行されたにもかかわらず、カウンターの値は12ではなく11となり、1回分の加算が失われてしまう。このようなデータの不整合を防ぐため、この一連の「読み込み・計算・書き込み」処理全体をクリティカルセクションとして定め、一度に一つのスレッドしか実行できないように保護する必要がある。 クリティカルセクションを保護するための排他制御を実現する技術には、いくつかの代表的な手法が存在する。最も基本的なものがミューテックス(Mutex)である。ミューテックスは「ロック」と「アンロック」という操作を用いて、クリティカルセクションへのアクセスを制御する。スレッドはクリティカルセクションに入る前にミューテックスのロックを獲得しようと試みる。もし他のスレッドが既にロックを保持していれば、そのロックが解放(アンロック)されるまで待機させられる。ロックを獲得できたスレッドのみがクリティカルセクションを実行でき、処理が完了したら必ずロックをアンロックして、他の待機しているスレッドが処理を進められるようにする。これにより、クリティカルセクションが同時に実行されることを防ぐ。セマフォ(Semaphore)も同様に排他制御に用いられる仕組みであるが、ミューテックスが単一のリソースへのアクセスを制御するのに対し、セマフォは利用可能なリソースの数をカウントすることで、複数のスレッドによるアクセスを許容することもできる。リソース数が1のセマフォはバイナリセマフォと呼ばれ、ミューテックスとほぼ同じ役割を果たす。これらの仕組みは強力であるが、使い方を誤るとデッドロックという新たな問題を引き起こす可能性がある。デッドロックとは、複数のスレッドが互いに相手が保持しているリソースの解放を待ち続け、全スレッドが永久に処理を先に進めなくなる状態である。例えば、スレッドAがリソースXをロックし、次にリソースYを要求、一方でスレッドBがリソースYをロックし、次にリソースXを要求するといった状況で発生する。このような問題を回避するためには、リソースを獲得する順序を全てのプロセスで統一するなど、慎重な設計が求められる。このように、クリティカルセクションの特定と適切な排他制御の実装は、並行プログラミングにおける正確性と安定性を確保するための根幹をなす技術である。

クリティカルセクション (クリティカルセクション) とは | 意味や読み方など丁寧でわかりやすい用語解説