iOS GCD之dispatch_semaphore学习

前几天看了大神YY写得YYCache源码,虽然没怎么看懂,但也学到了一点新东西吧,首先就是线程安全这一块,大神在介绍文章中也提到了选择保证线程安全的思路,其中就有dispatch_semaphore,当然我之前对此是一无所知的,大神在另一篇文章中也提到了这个东西,而且此方法性能也不错:

大神做的图.png

于是乎我就想研究下这个怎么使用,以下也是我根据网上搜索的资料再加自己的理解写的。

首先,我理解的dispatch_semaphore有两个主要应用 :
1. 保持线程同步
2. 为线程加锁


先看下相关的3个方法:

  • dispatch_semaphore_t dispatch_semaphore_create(long value):方法接收一个long类型的参数, 返回一个dispatch_semaphore_t类型的信号量,值为传入的参数
  • long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout):接收一个信号和时间值,若信号的信号量为0,则会阻塞当前线程,直到信号量大于0或者经过输入的时间值;若信号量大于0,则会使信号量减1并返回,程序继续住下执行
  • long dispatch_semaphore_signal(dispatch_semaphore_t dsema):使信号量加1并返回

介绍完了相关方法,下面开始介绍两种应用

保持线程同步

先看代码

   dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
   dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
   __block int j = 0;
   dispatch_async(queue, ^{
        j = 100;
        dispatch_semaphore_signal(semaphore);
   });
        
   dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
   NSLog(@"finish j = %zd", j);

结果输出 j = 100;
如果注掉dispatch_semaphore_wait这一行,则 j = 0;
注释: 由于是将block异步添加到一个并行队列里面,所以程序在主线程跃过block直接到dispatch_semaphore_wait这一行,因为semaphore信号量为0,时间值为DISPATCH_TIME_FOREVER,所以当前线程会一直阻塞,直到block在子线程执行到dispatch_semaphore_signal,使信号量+1,此时semaphore信号量为1了,所以程序继续往下执行。这就保证了线程间同步了。

为线程加锁

先看代码:

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
        
for (int i = 0; i < 100; i++) {
     dispatch_async(queue, ^{
          // 相当于加锁
          dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
          NSLog(@"i = %zd semaphore = %@", i, semaphore);
          // 相当于解锁
          dispatch_semaphore_signal(semaphore);
      });
}

注释:当线程1执行到dispatch_semaphore_wait这一行时,semaphore的信号量为1,所以使信号量-1变为0,并且线程1继续往下执行;如果当在线程1NSLog这一行代码还没执行完的时候,又有线程2来访问,执行dispatch_semaphore_wait时由于此时信号量为0,且时间为DISPATCH_TIME_FOREVER,所以会一直阻塞线程2(此时线程2处于等待状态),直到线程1执行完NSLog并执行完dispatch_semaphore_signal使信号量为1后,线程2才能解除阻塞继续住下执行。以上可以保证同时只有一个线程执行NSLog这一行代码。

如有错误, 欢迎批评指正。

参考:
GCD 学习(八) dispatch_semaphore
iOS --- 线程安全之semaphore
YYCache 设计思路

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

推荐阅读更多精彩内容

  • Managing Units of Work(管理工作单位) 调度块允许您直接配置队列中各个工作单元的属性。它们还...
    edison0428阅读 8,078评论 0 1
  • 锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...
    LiLS阅读 1,566评论 0 6
  • 原创内容,转载请注明出处: //www.greatytc.com/p/ac11fe7ef78c 前言 多线...
    抱紧我的小鲤鱼阅读 8,846评论 6 78
  • 原文地址 http://www.cnblogs.com/kenshincui/p/3983982.html 大家都...
    怎样m阅读 1,321评论 0 1
  • 姓名:陈芬 公司:宁波慈星股份有限公司 宁波盛和塾《六项精进》224期学员,利他二组学员 【日精进打卡第76天】 ...
    龙芬浩阅读 181评论 0 0