GCD-信号量

1.信号量介绍

        // 创建信号, 信号计数为2
        // value 一般控制任务最大并发数, 此时允许执行2个任务
        let sem = DispatchSemaphore(value: 2)
        // 等待, 信号计数减一
        sem.wait()
       // 释放信号, 信号计数加一
        sem.signal()

2.信号量应用

2.1信号量控制任务并发数, 通过设置信号计数

        let sem = DispatchSemaphore(value: 2)
        // 并发队列
        let queue = DispatchQueue(label: "", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
        // 添加任务
        queue.async {
            sem.wait()
            print("1")
            sleep(2)
            sem.signal()
        }
        queue.async {
            sem.wait()
            print("2")
            sleep(2)
            sem.signal()
        }
        queue.async {
            sem.wait()
            print("3")
            sleep(2)
            sem.signal()
        }
        queue.async {
            sem.wait()
            print("4")
            sleep(2)
            sem.signal()
        }
// 执行结果 2个2个打印 例如  1  2  ,  4  3

2.2信号量监听所有任务完成

  let sem = DispatchSemaphore(value: 2)
     //  并发队列
        let queue = DispatchQueue(label: "", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
     // 添加任务
        queue.async {
            print("1")
            sleep(2)
            print("done")
            sem.signal()
        }
        
        queue.async {
            print("2")
            sleep(2)
            print("done")
            sem.signal()
        }
        
        queue.async {
            print("3")
            sleep(2)
            print("done")
            sem.signal()
        }
        
        queue.async {
            print("4")
            sleep(2)
            print("done")
            sem.signal()
        }
        
// 此处监听
        queue.sync {
            sem.wait()
            sem.wait()
            sem.wait()
            sem.wait()
            print("all done")
        }

2.3信号量加锁, 设置信号计数为0

let sem = DispatchSemaphore(value: 0)

     let queue = DispatchQueue(label: "", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
     
     queue.async {
         print("1")
         sleep(2)
         sem.signal()
     }

     queue.async {
         sem.wait()
         print("2")
         sleep(2)
     }

3.信号量原理

  • dispatch_semaphore_wait 信号量等待,内部是对并发数做自减操作,如果为 小于0,会执行_dispatch_semaphore_wait_slow然后调用_dispatch_sema4_wait是一个do-while,知道满足条件结束循环
  • dispatch_semaphore_signal 信号量释放 ,内部是对并发数做自加操作,直到大于0时,为可操作
  • 保持线程同步,将异步执行任务转换为同步执行任务
  • 保证线程安全,为线程加锁,相当于自旋锁

4.参考文章

https://www.jianshu.com/p/1b45f579fc9f

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容