Day: November 8, 2007

breakとcontinue

繰り返し制御breakとcontinueはfor文,while文,until文(このページではこの三つをループと呼ぶ)で使用できるコマンドである.breakcontinue break breakはループを抜けるように指示する.while :doecho hogebreakdone上の例で:はtrueコマンドと同じである.trueコマンドは必ずtrueを返す.すなわち上の例は無限ループだが,hogeと一回表示したあとbreak文でループを抜ける.breakは一つの数値パラメータをとることができる.この数値(正の整数)で抜けるループの数を指定することができる. continue continueは次の繰り返しに飛ぶように指示する.while :doecho hogecontinueecho fugadone上の例も無限ループである.hogeを表示したあと,continueによって次の繰り返しに飛ぶ.したがって,fugaと表示されることはない.continueも一つの数値パラメータをとることができる.この数値(正の整数)でどのループの次の繰り返しに飛ぶかを指定できる.

セマフォ

共有メモリの話題に入る前の準備としてセマフォについて記述する.同期の問題セマフォとはセマフォを使ってみるセマフォと共有メモリ 同期の問題 二つのプロセス(もしくはスレッド)A,Bが共有する変数xがあったとする.そしてA,B両者がxに1を足すとする.xが0なら処理後のxの状態が2になっていることを期待してみる.Aがx(=0)の値を読み込む.Aがx(=0)に1を足してそれをxに書き込む.Bがx(=1)の値を読み込む.Bがx(=1)に1を足してそれをxに書き込む.この時x=2.上は「たまたま」正常なタイミングで動作した場合である.もしかしたら以下の状況なるかもしれない.Aがx(=0)の値を読み込む.Bがx(=0)の値を読み込む.Aがx(=0)に1を足してそれをxに書き込む.Bがx(=0)に1を足してそれをxに書き込む.この時x=1.期待に反してx=1となってしまった.これは「たまたま」プロセスの切替えタイミングが悪く,同期をとって処理すべき変数xに対してA,Bが非同期で処理してしまったから起こった現象である.このような処理をクリティカルセクションという.誰かがxをクリティカルセクションを処理しているときに,別の誰かはxを処理できない様にする必要がある. セマフォとは 上の問題を解決するために,ロック変数yを考えてみる.変数yが0の時は別のプロセスはxに対して処理をせず,1なら処理をする.したがってA,Bはxに対して処理する前にyをチェック,変更する.先のタイミングが悪かったパターンは以下のようになる.Aはy(=1)を読み込む.Aはyが1なのでこれを0にする.Aがx(=0)の値を読み込む.Bはy(=0)を読み込む.Bはyが0なので待つ.Aがx(=0)に1を足してそれをxに書き込む.Aはyを1に戻す.Bはy(=1)を読み込む.Bはyが1なのでこれを0にする.Bがx(=1)の値を読み込む.Bがx(=1)に1を足してそれをxに書き込む.Bはyを1に戻す.この時x=2.これでうまくいった.が,よく考えるとyに対してもまた最初のxと同じ状況が発生し得る.これではきりがないので,それを処理する間プロセスの切替えがおこらない何かが必要になる.これがセマフォ(semaphore)である.セマフォはDijkstraが発表したらしい.先のyがセマフォだったとすると,あるプロセスがyを読み込んで値を変更するまでの間,他のプロセスはyに対して処理しないことが保証されている.すなわちセマフォに対する処理はアトミックであることが保証されている.セマフォについてまとめてみた.0か正の整数をとる.waitとsignalという二つの操作だけが可能.waitをしたとき,値が1より大きければ値をデクリメントする.0ならば待つ.signalをしたとき,値が0より大きくなるのを待っているプロセスがあれば,そのプロセスを再開する.なければ値をインクリメントする.バイナリセマフォは0と1の二値をとる.汎用セマフォは0と複数の正の値をとる(例えば0,1,2).こうすると,クリティカルセクションの処理は以下のようになる.セマフォにwait操作をする.クリティカルセクションの実行.セマフォにsignal操作をする.これで問題は解決する. セマフォを使ってみる セマフォを使用するための関数には以下の3つがある.int semget(key_t key, int nsems, int semflg)keyで指定したnsems個からなるセマフォ集合の識別子を取得する.semflgはオプションでパーミッションなどもここで設定する.semflgでIPC_EXCLを指定するとセマフォが一意となることが保証される(keyがセマフォのために既に使用されていればsemgetは失敗する).int semop(int semid, struct sembuf *sops, unsigned nsops);semidで指定したセマフォ集合の操作のメンバを操作する.sopsはセマフォに設定したい値を持つsembuf構造体のnsops個の配列である.int … More セマフォ