マルチスレッドで処理するプログラムを書いていると、同時にアクセスするとまずいリソースがあってそれでも別々のスレッドでアクセスしないといけない場合がままある。こんなとき、排他制御ってのをやってそういうリソースにアクセスするのは必ず1つのスレッドにするようにする。ここでは、DispatchSemaphoneを使ってやってみる。
counterを100回カウントアップする処理を100個並列処理して結果を表示するプログラムを書いてみた。(100個並列処理と書いたが実際には同時に何個動いているかは不明)
// セマフォを用意する。
let semaphore = DispatchSemaphore(value: 1)
var counter = 0
// counterをカウントアップする関数を用意する。
let op1 = {
for _ in 0..<100 {
semaphore.wait()
counter+=1;
semaphore.signal()
}
}
let queue = OperationQueue()
for _ in 0..<100 {
queue.addOperation(op1)
}
// キューにあるオペレーションが実行されて終わるのを待つ
queue.waitUntilAllOperationsAreFinished()
// counterを表示
// 10000って表示される。
// セマフォを使わないと10000以外の値になる場合がある。
print(counter)
これを実行すると必ず10000と表示される。semaphore.wait()、semaphore.signal()コメントアウトして実行すると、10000以外になることがある。