27.信号量

前言

一、 控制 GCD 最大并发数

let queue = DispatchQueue.init(label: "RyukieQueue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
let semaphore = DispatchSemaphore(value: 2)

for i in 0...5 {
    queue.async {
        _ = semaphore.wait(timeout: .distantFuture)
        print("<<< 下载开始:\(i) 日期:\(Date())")
        sleep(5)
        print("下载结束:\(i) >>> 日期:\(Date())")
        semaphore.signal()
    }
}
<<< 下载开始:1 日期:2021-09-11 08:28:56 +0000
<<< 下载开始:0 日期:2021-09-11 08:28:56 +0000

下载结束:0 >>> 日期:2021-09-11 08:29:01 +0000
<<< 下载开始:2 日期:2021-09-11 08:29:01 +0000
下载结束:1 >>> 日期:2021-09-11 08:29:01 +0000
<<< 下载开始:3 日期:2021-09-11 08:29:01 +0000

下载结束:2 >>> 日期:2021-09-11 08:29:06 +0000
<<< 下载开始:4 日期:2021-09-11 08:29:06 +0000
下载结束:3 >>> 日期:2021-09-11 08:29:06 +0000
<<< 下载开始:5 日期:2021-09-11 08:29:06 +0000

下载结束:5 >>> 日期:2021-09-11 08:29:11 +0000
下载结束:4 >>> 日期:2021-09-11 08:29:11 +0000

二、 源码解读

2.1 dispatch_semaphore_create

2.2 dispatch_semaphore_signal

2.3 dispatch_semaphore_wait

_dispatch_semaphore_wait_slow

_dispatch_sema4_wait

可以看出,内部其实是个 do-while 循环实现的。

三、 一个思考题

下面代码会是怎样的执行结果呢?

输出:

参考

Last updated

Was this helpful?