记录一个GCD信号量中wait(timeout: DispatchTime)的用法

734 阅读1分钟

GCD信号量的常见用法

一般来说,人们提到GCD信号量的用法,一般都会联想到并发数的控制,比如下面我们来一段代码:

let semaphoreSignal = DispatchSemaphore(value: 3)
        for i in 1...10 {
            DispatchQueue.global(qos: .background).async {
                semaphoreSignal.wait()
                print("第\(i)次执行任务")
                Thread.sleep(forTimeInterval: 2)
                semaphoreSignal.signal()
            }
        }

这个很简单,也很常用,没什么好说的。

但是当你翻开API的定义:

image.png 你就会发现,wait不只有一种方法,另外2种,我们很少用到,今天,偶然机会看到这个,觉得好奇,想一探究竟。

wait(timeout: DispatchTime)用来做什么的?

遇事不懂问文档,我们直接翻开文档看看:

image.png 文档说了,这个方法会减少一个信号量,如果计算之后,结果小于0,那么这个方法会等待增加一个信号量,timeout就是他的等待超时时间。它返回的结果会有2个枚举值:

image.png 既然文档这么说,我们就用代码来验证一下:

let semaphoreSignal = DispatchSemaphore(value: 0)
        DispatchQueue.global().async {
            let result = semaphoreSignal.wait(timeout: .now() + 1)
            if result == .timedOut {
                print("timeout")
            } else {
                print("success")
            }
        }
        
        DispatchQueue.global().asyncAfter(deadline: .now()+2, execute: DispatchWorkItem(block: {
            semaphoreSignal.signal()
        }))

image.png 打印超时,如果asyncAfter 设置0.5的话,则打印success。

原来还有这种用法,涨知识了。

那么它有什么使用场景呢?

一个简单的场景就是,比如在app启动的时候,我们要请求一个接口,接口按照我们正常的超时事件设置,如果我们用了信号量来进行同步请求,那么为了启动时间不能太长,是不是可以使用这个方法,如果超过多久,还没做完操作,我们就直接过掉呢?

欢迎补充使用场景....