並列処理のやり方について調べてたらこれらの単語が出てきたので調べてみました。
Critical section(危険領域)とは
- OSにおいて、データの一貫性を保つために、他のプログラムに邪魔されずに(Atomicに)実行されないといけない宣言やインストラクション
- 変数の読み書き等
- Sexy zoneの弟グループではない
Mutexとは
- 語源はMutual Exclusion(相互的排他)
- OSにおいてCritical sectionを安全に実行するための仕組み
- 一つの資源(メモリ等)に対してあるタスクが書き込みや読み込みを行っている間は他のタスクがアクセスできないようにロックする
- 可愛い動物の名前ではない
Semaphoreとは
- Mutexをより一般化したもので、OSにおいて一つの資源に対して1〜複数のあらかじめ決められた数のタスクがアクセスできるよう管理する仕組み/そのためのオブジェクト
- 基本の考え方
- Semaphoreオブジェクトには全てのスレッドからアクセスできる
- Semaphoreの内部にカウンターがあり、今何個のタスクがアクセスしてるかSemaphore自身が把握している
- 各スレッドはCritical sectionの前後でSemaphoreのAcquireオペレーションとReleaseオペレーションを行う
- SemaphoreのAcquireオペレーションをするとアクセスできるタスクの数が一個減る
- SemaphoreのReleaseオペレーションをするとアクセスできるタスクの数が一個増える
- Semaphoreのカウンター上限に達するとそれ以上Acquireオペレーションができなくなる = 他のタスクがCritical Sectionに進入できなくなる
- Critical sectionを終わったタスクがReleaseオペレーションをしてSemaphoreに空きができると他のタスクがAcquireできるようになる(これが「いってよし!」の状態みたいだからsemaphore=旗振り機と呼ばれる)
- めでたしめでたし
- 各言語でsemaphore用のクラスがあるっぽい
- 並列処理においてはサーバーがパンクしないようにスレッド数を制御するために使われることが多いらしい
- Javaの例(引用元: https://www.baeldung.com/java-semaphore)
class LoginQueueUsingSemaphore {
private Semaphore semaphore;
public LoginQueueUsingSemaphore(int slotLimit) {
semaphore = new Semaphore(slotLimit); // カウンターの上限を指定しsemaphoreを作る
}
boolean tryLogin() {
return semaphore.tryAcquire(); // semaphoreのカウンターが-1される
}
void logout() {
semaphore.release(); // semaphoreのカウンターが+1される
}
int availableSlots() {
return semaphore.availablePermits();
}
}