What is the purpose of Semaphore.wait(timeout: .now())?

元气小坏坏 提交于 2019-12-07 13:40:15

问题


Looking at some Apple code sample, I found this:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    // wait() is used to drop new notifications if old ones are still processing, to avoid queueing up a bunch of stale data.
    if metadataObjectsOverlayLayersDrawingSemaphore.wait(timeout: .now()) == .success {
        DispatchQueue.main.async {
            // Some processing...

            self.metadataObjectsOverlayLayersDrawingSemaphore.signal()
        }
    }
}

Context of the code: This is the delegate method when using video capture to detect a QR code (or any other code). Because it is triggered many times per second (if the camera stays on the same QR code), some kind of timeout is needed.

But how does DispatchSemaphore.wait(timeout: .now()) work? And why check if it is .success?


回答1:


The purpose is what the comment says:

wait() is used to drop new notifications if old ones are still processing, to avoid queueing up a bunch of stale data.

and it works as follows:

  • The semaphore is created with a value of one.
  • When metadataOutput is called the first time, wait(timeout: .now()) succeeds and decrements the value of the semaphore to zero. The processing of the data begins.
  • If metadataOutput is called again before the processing has completed, the semaphore still has a value of zero. Then wait(timeout:) would wait for the semaphore to become positive again, but since the timeout value is now(), it fails immediately and returns .timedOut. The effect is that the incoming data is ignored, the metadataOutput callback method returns immediately.
  • When the data processing on the has completed, the semaphore is signaled, which increases the value to one. As a consequence, the next time the callback is called, waiting for the semaphore will succeed and the data is processed again.

So in short:

  • wait(timeout: .now()) returns .success if a previously submitted block has signaled completion, in that case a new block is submitted for processing the incoming data.
  • wait(timeout: .now()) returns .timedOut if a previously submitted block is still running, in that case the incoming data is ignored.


来源:https://stackoverflow.com/questions/49632941/what-is-the-purpose-of-semaphore-waittimeout-now

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!