今天跟大家聊聊关于 GCD 中的信号量的使用.

网上有很多关于信号量的介绍, 这里只是结合本人一些理解和实际使用来分享给大家.

在GCD中有三个函数是semaphore的操作,分别是

1.创建一个semaphore 
dispatch_semaphore_create
2. 发送一个信号 
dispatch_semaphore_signal
会使信号量计数增加1.
3. 等待信号
dispatch_semaphore_wait
会使信号量计数减少1.

/usr/include/dispatch/semaphore.h 中关于函数的声明和定义, 注释很清晰.

这里特别需要注意的几个问题:

  1. 创建信号量的函数
    dispatch_semaphore_t dispatch_semaphore_create(long value);
    函数需要传入一个大于或者等于0的值, 传入小于0的值, 函数返回 NULL.
  2. 等待信号函数
    long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
    返回0表示成功, 非0表示超时, 会继续执行该函数后面的语句.
    关于参数 timeout, 后面细说.
  3. 发送信号函数
    long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
    返回非0值表示成功唤醒线程, 0表示没有唤醒.

下面结合实际应用场景, 说说信号量的使用和注意事项.

在开发过程中, 大家应该会有这样的需求

场景1:
等待上一个网络请求的返回结果, 再决定是否进行下一个网络请求.

示例代码:

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[NetReq request:^(BOOL ok) {    // 唤醒等待的线程dispatch_semaphore_signal(sema);
} onFail:^(int errorCode, NSString *errorMessage) {  // 唤醒等待的线程dispatch_semaphore_signal(sema);
}];  // 一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // 等待上面网络请求结束, 开始执行下面语句
[NetReq request...] 

场景2:
生产者和消费者问题

使用信号量可以解决该类型的问题.

示例代码

dispatch_semaphore_t signal = dispatch_semaphore_create(0);if (NULL == signal) {return;
}//消费者队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{while (true) {// 在超时时间内成功得到信号触发返回0值表示成功, 非0表示失败// 超时时间设置为DISPATCH_TIME_FOREVER, 表示一直等待, 其后语句被阻塞, 一直等到其被唤醒// DISPATCH_TIME_NOW, 表示不等待, 继续执行其后面的语句// 也可以指定时间, dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC)), 表示10s内等待, 超过10s, 继续执行下面语句long result = dispatch_semaphore_wait(signal, DISPATCH_TIME_NOW);// 超时了if (result != 0)  {continue;}// 被唤醒NSLog(@"1....消费 %@", self.lockData);[self.lockData removeObjectAtIndex:0];}});// 这里可以阻塞一段时间, 延时增加信号量来看看消费者队列中 wait 的情况sleep(5);//生产者队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{while (true) {[self.lockData addObject:@"0"];NSLog(@"0-------产出: %@", self.lockData);// 使信号量加1, 返回非0表示成功, 0表示失败long result = dispatch_semaphore_signal(signal);//失败if (0 == result) {//wait for a whilesleep(1);continue;}//成功//TODO:}});

关于超时参数的定义在注释中有详细说明.

现在你可以动手试一试了.

iOS 多线程: 信号量相关推荐

  1. iOS 多线程:『GCD』详尽总结

    原文链接:www.jianshu.com/p/2d57c7201- 感谢大家对这篇文章的喜欢和支持.为了不辜负大家的喜欢,也为了更好的让大家了解 iOS 多线程,以及 GCD 的相关知识,我对这篇文章 ...

  2. iOS 多线程使用示例

    iOS是一款非常流行的移动操作系统,它的多线程特性被广泛应用于各种应用程序中.在本文中,我们将介绍iOS多线程的使用示例,以帮助开发人员更好地理解和应用多线程技术. 多线程概述 在iOS中,多线程是指 ...

  3. IOS多线程开发详解

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

  4. iOS多线程详解:实践篇

    iOS多线程实践中,常用的就是子线程执行耗时操作,然后回到主线程刷新UI.在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于在iOS中除了主线程,其他子线程是独立 ...

  5. iOS多线程资源共享的控制方法

    1.  关于多线程的同步问题 使用多线程有许多我们众所周知的优点,比如响应度高.充分发挥多核处理器的性能等.但是每个线程的创建也都是有一定的成本.线程同步的官方解释 :协同步调,让多个线程按照预定的先 ...

  6. iOS多线程开发:几个容易被忽略的细节(马甲包)

    一般情况下,iOS开发者只要会使用GCD.@synchronized.NSLock等几个简单的API,就可以应对大部分多线程开发了,不过这样是否真正做到了多线程安全,又是否真正充分利用了多线程的效率优 ...

  7. iOS - 多线程的锁

    iOS - 多线程的锁 多线程同时访问同一块资源会造成资源抢夺,容易引发数据错乱和数据安全问题,此时我们需要保证资源同时只有一个线程访问,加锁就是为了解决这个问题. 常用的加锁方式:(性能由差到好) ...

  8. 「面向打野编程」iOS多线程:CGD

    「面向打野编程」iOS多线程:CGD 前言 参考网络其他文章而写,渣水平,抛砖引玉. 虽然Concurrent意思为并发,但由于队列的实际效果,以下称为并行队列. 当前iPhone的CPU核心数远小于 ...

  9. iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)

    2017-07-08 remember17 Cocoa开发者社区 目的 本文主要是分享iOS多线程的相关内容,为了更系统的讲解,将分为以下7个方面来展开描述. 多线程的基本概念 线程的状态与生命周期 ...

最新文章

  1. 01、WPF 中 URI 解析
  2. Android的消息机制简单总结
  3. Forefront Security For Exchange的反病毒测试
  4. Glide-源码分析(一)
  5. java 类的实例化没有属性值,java – JsonMappingException:无法实例化类型的值没有single-long-arg构造函数/工厂方法...
  6. 前端学习(120):css精灵和好处
  7. 一体台式计算机名称,【一体台式电脑】一体台式电脑品牌推荐,台式一体机电脑哪款好_什么值得买...
  8. mysql并行dml_MySql的回顾九DML表数据的增,删,改,与DDL库表的增删改,约束
  9. Atitit 架构师之道 attilax著 1.1. 认和评估系统需求, 2 1.2. 给出开发规范 2 1.3. ,搭建系统实现的核心构架, 2 1.4. 扫清主要难点的技术人员 2 1.5. 核
  10. vs2017 社区版本离线下载安装包
  11. ubuntu/window安装dukto
  12. java 比较日期大小(方法之一compare to 备忘)
  13. An error occurred while starting the application
  14. Illegal instruction 问题处理
  15. 【数据库原理】关系代数的实例和练习
  16. 苹果为啥要在iOS 9中使用新字体?
  17. java 完整子图_用JAVA求解最大连通子图
  18. ubuntu中安装卸载mysql8.0及修改密码
  19. 关于Manifest
  20. 从0开始建设saas - 优化篇(session访问的问题)

热门文章

  1. 北京成人学位英语考试视频学习全套教程
  2. 通过 order_id 获取 参与拼团的 人 的头像
  3. 利用RecordRTC.js实现H5录音功能
  4. 高通平台usb充电检测
  5. linux tomcat 启动 无法访问,Linux下 Tomcat 配置启动成功但是无法访问网页的问题【2019-09-25】...
  6. 2016年大数据发展趋势预测(30PPT)
  7. 机器学习笔记 - 什么是条件随机场?
  8. 北京网站域名服务器,北京域名服务器
  9. wsappx占用大量CPU,关闭Windows10的wsappx服务
  10. USACO入门以及提交格式