排他はいた制御せいぎょ

出典しゅってん: フリー百科ひゃっか事典じてん『ウィキペディア(Wikipedia)』
排他はいた制御せいぎょせずに ii+1 という2つのノードを同時どうじ連結れんけつリストからはず操作そうさおこなうと、結果けっかとして i+1 のノードがはずれないという状態じょうたいになりうる。

(はいたせいぎょ)とは、コンピュータ・プログラム実行じっこうにおいて、複数ふくすうプロセス利用りよう出来でき共有きょうゆう資源しげんたいし、複数ふくすうのプロセスからの同時どうじアクセスにより競合きょうごう発生はっせいする場合ばあいに、あるプロセスに資源しげん独占どくせんてき利用りようさせているあいだは、のプロセスが利用りようできないようにすること整合せいごうせいたも処理しょりことをいう。相互そうご排除はいじょまたは相互そうご排他はいたmutual exclusion)ともいう。最大さいだいkのプロセスが共有きょうゆう資源しげんにアクセスして場合ばあいを k-相互そうご排除はいじょという。

換言かんげんすれば1つのクリティカルセクション複数ふくすうのプロセス(またはスレッド)が同時どうじはいることをふせぐことである。クリティカルセクションとは、プロセスが共有きょうゆうメモリなどの共有きょうゆう資源しげんにアクセスしている期間きかんす。排他はいた制御せいぎょ問題もんだいは1965ねんエドガー・ダイクストラ並行へいこうプログラミング制御せいぎょにおける問題もんだい解法かいほういてあつかった論文ろんぶんあつかったのが最初さいしょである[1][2]

排他はいた制御せいぎょ重要じゅうようせいしめれいとして、片方向かたほうこう連結れんけつリストがある(みぎ)。このような連結れんけつリストからノードを削除さくじょするには、1つまえのノードにある、つぎのノードをすポインタを、削除さくじょしたいノードの、つぎのノードをすようにえる(たとえば、ノード i削除さくじょするには、ノード i-1 のnextポインタをノード i+1すようえる)。このとき、その連結れんけつリストを複数ふくすうプロセスが共有きょうゆうしているなら、2つのプロセスがそれぞれべつのノードを削除さくじょしようとしてつぎのような問題もんだいしょうじる可能かのうせいがある。

  • 2つのプロセスはそれぞれノード ii+1同時どうじ削除さくじょしようとする。どちらのノードも連結れんけつリストの途中とちゅうにあり、先頭せんとうでもさい後尾こうびでもないとする。
  • ノード i-1 のnextポインタはノード i+1すようえられ、ノード i のnextポインタはノード i+2すようえられる。
  • 両方りょうほう削除さくじょ処理しょり完了かんりょうした状態じょうたいると、ノード i-1 がノード i+1すようえられたために、ノード i+1連結れんけつリストにのこってしまう。

この問題もんだい排他はいた制御せいぎょほどこして複数ふくすう状態じょうたい更新こうしん処理しょり同時どうじおこなわれないようにすれば解決かいけつする。

排他はいた制御せいぎょ実施じっし[編集へんしゅう]

排他はいた制御せいぎょ実施じっしする手段しゅだんはハードウェアによるものとソフトウェアによるものがある。

ハードウェアによる方式ほうしき[編集へんしゅう]

シングルプロセッサシステムでは、あるプロセスがクリティカルセクションにあるとき禁止きんしするというのがもっと単純たんじゅん排他はいた制御せいぎょである。そのあいだ、いかなるみハンドラ動作どうさできない(それによって実質じっしつてきプリエンプションふせぐ)。この方式ほうしき効果こうかてきだが、同時どうじ様々さまざま問題もんだいもはらんでいる。クリティカルセクションがなが場合ばあい、クロックみが処理しょりされないためにシステム時刻じこく徐々じょじょおくれていくという事態じたい発生はっせいしうる。また、クリティカルセクションないでプロセスが停止ていしすると、のプロセスに制御せいぎょわたせなくなり、結果けっかとしてシステム全体ぜんたい停止ていしすることになる。μみゅーITRONなどでは、タスクえ(プリエンプションディスパッチ)を禁止きんしするという操作そうさもある。より上品じょうひん方式ほうしきとしてビジーウェイト相互そうご排他はいたする方式ほうしきもある。

ビジーウェイトはシングルプロセッサでもマルチプロセッサでも有効ゆうこうである。共有きょうゆうメモリと不可分ふかぶんテスト・アンド・セット命令めいれい使つかうことで、排他はいた制御せいぎょ実現じつげんする。プロセスは共有きょうゆうメモリじょう特定とくてい位置いちについて調しらべてあらたなをセットするという操作そうさ不可分ふかぶん実施じっしでき、それによっていちに1つのプロセスだけがフラグをセットできることを保証ほしょうする。フラグをセットできなかったプロセスはべつ処理しょりおこなってあとさい試行しこうするか、プロセッサをのプロセスにわたしてあとさい試行しこうするか、フラグをセットできるまでループしてさい試行しこうかえすといった動作どうさ可能かのうである。プリエンプションは可能かのうなので、この方式ほうしきではプロセスがフラグ(ロック)を保持ほじしたまま停止ていししてもシステム全体ぜんたい機能きのうつづける。

不可分ふかぶん操作そうさ命令めいれいほかにもいくつかの実装じっそうがあり、どれもデータ構造こうぞう排他はいた制御せいぎょ使つかえる。よくられるのはコンペア・アンド・スワップ (CAS) である。CAS命令めいれい使つかえば wait freeばれる排他はいた制御せいぎょ任意にんい共有きょうゆうデータに実施じっしできる。そのためには連結れんけつリストをつくり、かくノードが実行じっこうしたい操作そうさあらわすようにする。CAS命令めいれいはその連結れんけつリストにあたらしいノードを挿入そうにゅうするさい使用しようする。ノードの挿入そうにゅうはCAS命令めいれい使つかえばいちに1つのプロセスしか成功せいこうしない。失敗しっぱいしたプロセスはノード追加ついか処理しょり成功せいこうするまで試行しこうつづける。かくプロセスはこのデータ構造こうぞうのローカルなコピーを保持ほじでき、連結れんけつリストを走査そうさでき、リストのローカルコピーじょうかく操作そうさ実行じっこうできる。

ソフトウェアによる方式ほうしき[編集へんしゅう]

ハードウェアサポートを必要ひつようとする方式ほうしきとはべつに、ビジーウェイト使つかってソフトウェアのみで排他はいた制御せいぎょ実現じつげんする方式ほうしき存在そんざいする。たとえば、つぎのようなものがある。

これらのアルゴリズムはアウト・オブ・オーダー実行じっこうはたらくプラットフォームじょうでは動作どうさできない(ただし、メモリバリア実現じつげんする機械きかい命令めいれいっているCPUプラットフォームの場合ばあいのぞく)。アルゴリズム実施じっしちゅう、メモリ操作そうさはプログラミングしたとおりにおこなわれなければならない[4]

OSのマルチスレッドライブラリが同期どうき機構きこう提供ていきょうしているなら、それを使つかほうのぞましい。ハードウェアによる方式ほうしき利用りよう可能かのうならばそれを使つかって実装じっそうされているだろうし、そうでないならばソフトウェアによる方式ほうしき利用りようしているだろう。たとえばOSのライブラリを使つかい、スレッドが他者たしゃすで獲得かくとくしているロックを獲得かくとくしようとしたとき、OSはそのスレッドを中断ちゅうだんさせてコンテキストスイッチ動作どうさ可能かのうほかのスレッドを動作どうささせたり、動作どうさ可能かのうほかのスレッドがなければプロセッサをはぶけ電力でんりょく状態じょうたいにしたりといったことをする可能かのうせいがある。したがって、ほとんどの現代げんだい排他はいた制御せいぎょ技法ぎほうはキューイングとコンテキストスイッチを使つかレイテンシとビジーウェイト時間じかん削減さくげんしようとする。しかし、スレッドを中断ちゅうだんさせて再開さいかいさせるのにかかる時間じかんがスレッドがロックを獲得かくとくできるまでの時間じかんよりなが場合ばあいかぎり、スピンロックほうてきしているといえる。

高度こうど排他はいた制御せいぎょ[編集へんしゅう]

これまでに説明せつめいした方式ほうしき使つかい、つぎのような同期どうきプリミティブが構築こうちくできる。

排他はいた制御せいぎょおおくの形式けいしきには副作用ふくさようがある。たとえば、古典こてんてきセマフォデッドロックこしうる。あるプロセスがあるセマフォを獲得かくとくし、べつのプロセスがべつのセマフォを獲得かくとくした状態じょうたいで、たがいに相手あいて獲得かくとくしたセマフォが解放かいほうされるのをつづけることがかんがえられる。よくある副作用ふくさようとしてリソーススタベーションがあり、その場合ばあいプロセスは処理しょり完遂かんすいするのに十分じゅうぶん資源しげんけっしてられない。また、優先ゆうせん順位じゅんい逆転ぎゃくてんてい優先ゆうせんのスレッドのせいでこう優先ゆうせんのスレッドがたされる現象げんしょうであり、レイテンシがながくなり、みへの反応はんのうわるくなる。

排他はいた制御せいぎょかんする研究けんきゅうおおくはそういった副作用ふくさよう排除はいじょすることを目的もくてきとしており、たとえばLock-freeとWait-freeアルゴリズムはブロッキングされずに処理しょり進行しんこうすることを保証ほしょうする。完璧かんぺき方法ほうほうはまだつかっていない。

留意りゅういすべき現象げんしょう性質せいしつ[編集へんしゅう]

デッドロック[編集へんしゅう]

排他はいた制御せいぎょによりロックされた資源しげんのユーザからアクセス要求ようきゅうされたとき両者りょうしゃたがいに使用しようちゅう資源しげん解放かいほうされるのをブロック状態じょうたいつという状況じょうきょう発生はっせいすることがある。2つ以上いじょうのユーザあいだしょうじるが、この状態じょうたいではどのユーザも資源しげん解放かいほうったまま処理しょりすすまずに停止ていし状態じょうたいとなる。 このような状態じょうたいをデッドロックという。

ライブロック(livelock[編集へんしゅう]

デッドロックと同様どうよう排他はいた制御せいぎょによりロックされた資源しげんに、複数ふくすうのユーザからアクセス要求ようきゅうされたときに、おたがいに資源しげん解放かいほうされるのをビジー状態じょうたいつという状況じょうきょう発生はっせいする。デッドロックでは個々ここのユーザにおける資源しげん獲得かくとくのための処理しょり進行しんこうしないのにたいし、ライブロックでは資源しげん獲得かくとく処理しょり進行しんこうしているにもかかわらず、どのユーザも資源しげん獲得かくとくできない状況じょうきょうである。

たとえば、せまみちあるいていて対面たいめんした歩行ほこうしゃ2めいが、おたがいに相手あいてけようとした方向ほうこううごいてしまい、けられないということる。つぎに、ぎゃく方向ほうこうけようしてけられない。このような状況じょうきょうつづいて、何時いつまでってもすれちがうことができないという状況じょうきょうにあたる。(リソーススタベーション参照さんしょう)

フェアネス(fairness[編集へんしゅう]

共有きょうゆう資源しげん利用りようしたいユーザが、いつかは共有きょうゆう資源しげん利用りようできる」という、排他はいた制御せいぎょアルゴリズムがたすべき性質せいしつ。 フェアネスがたされない場合ばあいれいであるが、えき切符きっぷに3だい券売けんばいがあって、かく券売けんばい行列ぎょうれつ出来できているとき、ならんだ行列ぎょうれつすすみがおそ場合ばあい行列ぎょうれつ後尾こうびならびなおす戦略せんりゃく採用さいようすると、うんわるければなんまでってもけん購入こうにゅうできないということがこりうる。

k-バイパス(k-bypass[編集へんしゅう]

共有きょうゆう資源しげんへのアクセス要求ようきゅうしたユーザが、から要求ようきゅうした最大さいだいkのユーザによって、さき資源しげん使つかわれてしまう可能かのうせいがあるということをあらわす、フェアネスの度合どあいをはか指標しひょうである。

コンボイ(Convoy[編集へんしゅう]

あるプロセスがロックを獲得かくとくしたにもかかわらず、そのプロセスがげんにCPUじょう実行じっこうされていないため、実質じっしつてきにどのプロセスやCPUもクリティカルセクションない処理しょり実行じっこうしていない状態じょうたい。ロックの目的もくてきらしわせると無駄むだ状態じょうたいである。ロックの獲得かくとくからクリティカルセクションない処理しょり開始かいしするまでに遅延ちえん発生はっせいしたりコンテキストスイッチの回数かいすう増加ぞうかするため、システムの応答おうとう遅延ちえん増加ぞうか全体ぜんたい性能せいのう劣化れっかまねく。

ロックを解放かいほうしたプロセスが、そのロックをってスリープしているプロセスのいずれかへロックの所有しょゆうけん直接ちょくせつわたしてしまう実装じっそうになっていると発生はっせいしやすくなる。対策たいさくとして、ロックを獲得かくとくしたいプロセスはかなら自分じぶん自身じしんでロック獲得かくとくこころみる実装じっそうにすることにより問題もんだい軽減けいげんされる。典型てんけいれいスピンロックで、ロックを獲得かくとくしたいプロセスは仕様しようじょうけっしてスリープしない。ぎゃくにロックちのプロセスがスリープする場合ばあいは、スリープ終了しゅうりょうからロック獲得かくとくまでの手順てじゅんによってはコンボイにおちいりやすくなる。

優先ゆうせん上限じょうげんプロトコル優先ゆうせんがサポートされている環境かんきょうにて、優先ゆうせん継承けいしょうはロック所有しょゆうちゅうのプロセスよりも優先ゆうせんたかいプロセスがロックを獲得かくとくしようとした場合ばあいに、それぞれこの問題もんだい優先ゆうせん依存いぞんした別々べつべつのアプローチで解決かいけつしようとする。ただし、コンボイの本質ほんしつは「プロセスがげんにCPUじょう実行じっこうちゅうではないにもかかわらずロックを獲得かくとくしてしまう」ことにあり、優先ゆうせん有無うむには関係かんけいないため、両者りょうしゃとも問題もんだい直接ちょくせつ解決かいけつするものではない。[5]スピンロックがコンボイの問題もんだいのがれていることからあきらかなように、「プロセスが自力じりきでロックを獲得かくとくする」実装じっそう制限せいげんすることが本質ほんしつてき解決かいけつとなる。

脚注きゃくちゅう[編集へんしゅう]

  1. ^ E. W. Dijkstra. Solution of a problem in concurrent programming control. Communications of the ACM, 8(9), page 569, September, 1965.
  2. ^ a b Taubenfeld. The Black-White Bakery Algorithm. In Proc. Distributed Computing, 18th international conference, DISC 2004. Vol 18, 56-70, 2004
  3. ^ L. Lamport. A new solution of Dijkstra’s concurrent programming problem. Communications of the ACM, 17(8):453–455, August 1974.
  4. ^ Holzmann, G.J. Bosnacki, D. “The Design of a Multicore Extension of the SPIN Model Checker”, Software Engineering, IEEE Transactions on, vol. 33, no. 10, pp.659-674, Oct. 2007
  5. ^ 優先ゆうせん上限じょうげんプロトコルは、ロックを獲得かくとくしたいプロセスがすべて上限じょうげんいっぱいの優先ゆうせんであると機能きのうしない。優先ゆうせん継承けいしょうは、ロック獲得かくとくちゅうのプロセスよりも優先ゆうせんたかいプロセスがロックを獲得かくとくしようとするまで動作どうさしない。

参考さんこう文献ぶんけん[編集へんしゅう]

  • Michel Raynal: Algorithms for Mutual Exclusion, MIT Press, ISBN 0-262-18119-3
  • Sunil R. Das, Pradip K. Srimani: Distributed Mutual Exclusion Algorithms, IEEE Computer Society, ISBN 0-8186-3380-8
  • Thomas W. Christopher, George K. Thiruvathukal: High-Performance Java Platform Computing, Prentice Hall, ISBN 0-13-016164-0
  • Gadi Taubenfeld, Synchronization Algorithms and Concurrent Programming, Pearson/Prentice Hall, ISBN 0-13-197259-6

関連かんれん項目こうもく[編集へんしゅう]

外部がいぶリンク[編集へんしゅう]