12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Swift:DispatchSemaphoreの仕様メモ

Posted at

DispatchSemaphoreを使うと非同期処理を同期的に処理するために待機したりできる。

let semaphore = DispatchSemaphore(value: 0)

みたいな感じで初期化できるがこのvalueがキモ。semaphoreは内部でカウンターを持つ。valueはカウンターの初期値となる。

  • semaphore.signal()をするとカウンターが+1される
  • semaphore.wait()をするとカウンターが-1される

wait()はカウンターが0以上になるまで処理を止めて待機状態になる(以降の行が実行されないで止まる)。初期値が0の場合、wait()をn回叩いたら、signal()がn回叩かれるまで処理が止まるという感じ。

タイムアウトのあるwaitもある。→wait(timeout: )

使い方
// 3秒でタイムアウトするwait
switch semaphore.wait(timeout: .now() + 3) {
case .success:
// 3秒以内にsignalをもらった
// うまくいったときの処理
case .timedOut:
// 3秒待ってもsignalが来なかった
// タイムアウトの時の処理
}

ここで内部カウンターについて注意点。

  • semaphore.wait(timeout:)の行に到達した時点で-1される
  • .successの場合、外部でsignalが叩かれているはずなので+1される
  • .timedOutの場合、外部でsignalが叩かれていないけれど、+1される

つまり、wait(timeout:)の場合、成功しようが失敗しようがカウントは+1される。
これを知らないとsemaphoreのカウンターをうまく処理できずに無限ループになったり、意図通りのループにならなかったりするかも。

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?