出典(authority):フリー百科事典『ウィキペディア(Wikipedia)』「2014/03/11 00:32:29」(JST)
ウィキペディアにおける編集の競合については、Help:編集の競合をご覧ください。 |
競合状態(きょうごうじょうたい、英: Race Condition、レースコンディション、または英: Race Hazard、レースハザード)は、システムや処理過程の問題であり、処理過程の出力結果がイベントなどの順序やタイミングと予期しない(かつ危険な)依存関係にある場合をいう。本来の意味は、2つの電気信号が競合していずれかが出力に影響を与える状態である。
競合状態は設計の不十分な電子工学システム、特に論理回路で発生するが、コンピュータソフトウェアでもよく発生する。
競合状態の典型例は論理回路システムで入力が変化するときに発生するものである。ある出力が入力の状態に依存する場合、それは定常状態の信号に関して定義されるだけかもしれない。入力の状態が変化するとき、電子システムの物理特性によって出力が変化するまである程度の遅延が生じる。その間、出力は定義された状態以外の不安定な状態となる可能性がある。このような一時的な障害を許すシステムもあるが、例えばその出力信号が他のメモリなどを含むシステムのクロックとして使用される場合、システムは設計されたものとは異なった振る舞いをするかもしれない。
例えば、2入力ANDゲートで論理信号 X とその否定 NOT X を入力にしている場合を考えてみる。理論上、その出力(X AND NOT X)はONになることはない。しかし、信号 X がそのまま入力される側と NOT ゲートを通して入力される側で遅延時間に差があった場合、短い時間ではあるが、一時的にANDゲートの出力がONになることがある。
適切な設計技法により設計者は競合状態を認識して事前にそれを排除することができる(カルノー図)。他にも準安定状態(Metastable state)が発生することもある。
競合状態はソフトウェアでも発生する。特に複数のプロセスやスレッドが通信しながら動作する場合に発生する。
以下に単純な例を示す。
2つのスレッド T1 と T2 がそれぞれグローバルな整数を 1 ずつインクリメントしていくとする。理想的には以下のような順序で処理したい。
この例では、i の最終的な値として 2 を期待している。しかし、二つのスレッドは並行に動作し、ロックや同期などの機構を使用しないため、処理結果は間違ったものとなる可能性がある。以下にそのような場合のシナリオを示す。
i の最終値は期待されている 2 ではなく 1 となる。
別の例として以下の擬似コードでは、二つのタスクを示している。
global integer A = 0; // A の値をインクリメントして "RX" を表示する // 端末からの割り込みが発生するたびに起動されるものとする task Received() { A = A + 1; print "RX"; } // A が偶数のときだけそれを表示する // 1秒間隔で起動されるものとする task Timeout() { if (A is divisible by 2) { print A; } }
出力結果は以下のようになるだろう:
0 0 0 RX RX 2 RX RX 4 4
ここで、以下のような順序でイベントが発生する場合を考える:
A
を調べ、偶数だったので、次の "print A" を実行しようとする。ミューテックスは、コンカレントプログラミングにおけるこのような問題に対処するために使われる。
ファイルシステムにおけるファイルロックは一般的解決法を提供する。もっと面倒だが根本的な解決策としては、あるファイルについてひとつのプロセスが排他的なアクセス権を持ち(デーモンのような動作をする)、他のプロセスがそのファイルにアクセスしたいときはプロセス間通信でそのプロセスに依頼するという方式が考えられる(もちろん、その際にプロセスレベルの同期が必要である)。
ネットワークでは、IRCのような分散チャットネットワークがあり、ユーザーは新たなチャンネルを開始させるとそのオペレータ特権を得る。異なるサーバを使用中の2人のユーザーが同じ名前のチャンネルを同時に作成しようとする場合、それぞれのサーバは対応するユーザーそれぞれにオペレータ特権を与えてしまう。これは別のサーバからの信号が届く前に特権を与えてしまうことから発生した。なお、現在では多くのIRCサーバの実装でこの問題が解決されている。
この場合の競合状態では、リソース共有のコンセプトでネットワークの状態を隠して、各サーバが自由に状態を変更した後でネットワーク上のサーバにその変化を通知している。しかし、ネットワークによる遅延(レイテンシ)があるためにこのような競合状態が発生するのである。この競合状態を解決するには、何らかの中心となるシステムを用意してチャンネルの生成と特権の付与を集中管理する必要がある。ユーザーがそのような解決策を受け入れられない場合、競合状態を検出して後からそれを訂正するなどの処理が必要となる。
競合状態の特に問題となる例として、放射線療法機器(Therac-25)の事故がある。他の例として、オハイオ州の FirstEnergy 社の電力管理システムの事故がある。このシステムは警報装置に競合状態を発生する問題があった。3本のたるんだ送電線が同時に外されたとき、競合状態が発生して監視要員に警報が届かなかった。このソフトウェア上の問題によって2003年北アメリカ大停電が発生した。
述語(例えば認証のための真理値を返す演算子か関数)のチェックと使用にかかわる競合状態というものがある。チェック時点と使用時点で状態を変更できるなら、競合状態が発生する。このような競合状態を発生させるバグがコンピュータセキュリティに関わるコードに存在すると、セキュリティホールになる可能性がある。例えば、ファイルのアクセス権をチェックした後で実際のファイルオープンをする場合(あくまでもオペレーティングシステム内のこと)、チェックとオープンの間にファイルをすりかえる(例えばシンボリックリンクにする)と通常アクセスできないファイルにアクセスできる(これは、オペレーティングシステムにバグがある場合の話であって、一般に可能という話ではない)。
常に1ビットだけ入力が変化すると仮定している非同期有限状態機械は、同時に複数の入力ビットが変化すると障害が発生する。これに対する解決策としては、マシンを設計する際に各状態が検知する入力ビットの変化を1ビットに限定することである。
以下、英文
全文を閲覧するには購読必要です。 To read the full text you will need to subscribe.
リンク元 | 「対抗」「競争」「competition」「競合性」「競合的」 |
拡張検索 | 「非競合性」「競合的阻害剤」「不競合的」 |
.