iOS开发 多线程的高级应用-信号量semaphore

2023-11-16

在iOS开发的道路上,多线程的重要性不言而喻. 大部分我们都停留在基础的使用上面.缺乏高级应用. 缺乏提升,是因为我们面对他太少,复杂的事情重复做,复杂的事务基础化. 差距就是这样拉开了

言归正传: 今天讲讲GCD的高级应用之信号量篇

一, 信号量的本质:
信号量的本质是数据操作锁, 它本身不具有数据交换的功能,而是通过控制其他的通信资源来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能.

二: 信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:
P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行
V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

举个例子,就是 两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为 当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

三: iOS中GCD的信号量函数解析:

dispatch_semaphore_t  semaphore = dispatch_semaphore_create(2);

这行代码创建了一个信号量,同时指明了最多有2个资源可以访问该”临界区域”

dispatch_semaphore_signal(semaphore)

这行代码 提高信号量 , 信号量计数 + 1

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

这行代码 降低信号量 , 信号量计数 - 1

特别注意 当信号为0(零),在执行 dispatch_semaphore_wait 语句时,信号量计数小于0 ,阻塞当前线程.

四: GCD的信号量应用场景: 控制最大并发量, 控制资源的同步访问,如数据访问,网络同步加载.

例如我有这样的一段代码,假设需求是控制两个网络的执行顺序 如想让请求一完成之后,在进行网络请求二,然后在进行网络请求N (实现的方式有多种多样)在此处主要讨论GCD semaphore 信号量的使用:

首先大家看看这段代码带来的问题

-(void)testSemaphore{

    NSLog(@"current1:%@",[NSThread currentThread]);

    dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);

    [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {

        dispatch_semaphore_signal(semaphore);

    } failure:^(NSError * _Nullable error, NSInteger statusCode) {
        dispatch_semaphore_signal(semaphore);
    }];

    NSLog(@"你会来这儿吗1");
    NSLog(@"current1:%@",[NSThread currentThread]);
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

    NSLog(@"你会来这儿吗2");

    [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {
        NSLog(@"resqueue2:");
    } failure:^(NSError * _Nullable error, NSInteger statusCode) {
    }];
}

下面我用一张截图进行说明,主要是用于说明 dispatch_semaphore_wait 会阻塞当前线程

这里写图片描述

接下来这三个网络请求使用GCD信号量实现同步,并且不阻塞主线程

- (IBAction)gcd2:(id)sender {

   dispatch_queue_t queue = dispatch_queue_create("AkSemaphore", NULL);

   dispatch_async(queue, ^{
      NSLog(@"current1:%@",[NSThread currentThread]);
      dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);

      [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {

           dispatch_semaphore_signal(semaphore);
           NSLog(@"resqueue1:");
       } failure:^(NSError * _Nullable error, NSInteger statusCode) {
           dispatch_semaphore_signal(semaphore);
       }];

       NSLog(@"你会来这儿吗1");

       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

       NSLog(@"你会来这儿吗2");

       [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {
           NSLog(@"resqueue2:");
           dispatch_semaphore_signal(semaphore);
       } failure:^(NSError * _Nullable error, NSInteger statusCode) {
           dispatch_semaphore_signal(semaphore);
       }];

       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

        NSLog(@"你会来这儿吗3");
       [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {
           NSLog(@"resqueue3:");   
       } failure:^(NSError * _Nullable error, NSInteger statusCode) {
       }];
    });
}

这里写图片描述

接下来讲一下控制网络的并发访问 :
假如现在有一个这样的需求,需要先下载50张图片, 一般异步会开启新的线程,但过多的线程 数与项目的性能是成反比的 . 所以控制并发,提高性能则尤为重要 : 实例代码如下

- (void)testGCD3{
    dispatch_semaphore_t semaphore =  dispatch_semaphore_create(5);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    for (int i=0;i<100 ; i++) {

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        dispatch_async(queue, ^{
            NSLog(@"i = %d",i);
            //此处模拟一个 异步下载图片的操作
            sleep(2);
            dispatch_semaphore_signal(semaphore);
        });
    }
}

代码讲解如下图:

这里写图片描述

作者:谁先注册了阿K
链接:https://www.jianshu.com/p/26a82224a3ff
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS开发 多线程的高级应用-信号量semaphore 的相关文章

  • iOS进阶_密码学进阶(一.对称加密算法简介)

    加密算法 HASH 散列函数 不可逆 密码 识别 文件 识别 以下两种加密算法 都是可逆的 明文 gt 加密 gt 密文 密文 gt 解密 gt 明文 对称加密 传统加密算法 加密和解密使用同一个 密钥 密钥的保密工作就非常的重要 密钥会定
  • iOS架构师_观察者模式

    定义 观察者模式 有时又被称为模型 视图 View 模式 源 收听者 Listener 模式或从属者模式 一个目标物件管理所有相依于它的观察者物件 并且在它本身的状态改变时主动发出通知 这通常透过呼叫各观察者所提供的方法来实现 此种模式通常
  • iOS进阶_密码学(四.抽取登录网络请求的单例)

    登录业务逻辑完善 在网络开发中 一般会有一个单例负责所有的网络请求 将这个网络登录的部分代码抽取出来 新建一个 类 复制方法 调整参数 测试登录能否成功运行 WTNetworkTools h import
  • iOS中socket通信---基于CocoaAsyncSocket实现

    前言 最近项目中涉及到socket通信这块 所以有幸有时间大概看了一下这一块 目前还在实现阶段 因此现在还不能去些具体的实现过程 现在只大概描述一下这几天看的资料和自己的一点心得吧 等项目实现之后会将具体的实现流程写出来以供大家参考 Soc
  • iOS进阶_GCD(二.GCD串行队列&并发队列)

    GCD 核心概念 将任务添加到队列 指定任务执行的方法 任务 使用block封装 block 就是一个提前准备好的代码块 在需要的时候执行 队列 负责调度任务 串行队列 一个接一个的调度任务 并发队列 可以同时调度多个任务 任务执行函数 任
  • iOS开发多线程-线程间的通信

    一 简单说明 线程间通信 在1个进程中 线程往往不是孤立存在的 多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后 转到另1个线程继续执行任务 线程间通信常用方法 void perfo
  • iOS进阶—Runtime基础

    iOS进阶 目录 GitHub参考 RunTime 基础 一个程序的执行过程 大概就是代码 gt 编译链接 gt 执行 C语言 import
  • iOS架构-组件化(项目实战-项目首页架构)

    UI架构设计 设计模式 外观模式 代理模式 适配器模式 adapter 注意 一版本只是搭建结构 一 1 0 Tab搭建 二 1 1 新增UICollectionView 主页 gt 整体设计基于 gt UICollectionView 滑
  • iOS核心动画CoreAnimation系统进阶(赛贝尔曲线-菜单侧滑动画拆分动画详解)

    我们知道动画是基于绘制的 多次绘制贝塞尔的过程就会形成动画 流畅的动画效果会给用户带来不一样的使用体验 下面我们就让App开发中经常使用到的侧滑动画进行拆分详解 效果图如下 为侧滑动画封装一个slideMenuView 绘制侧滑动画需要下面
  • iOS架构-组件化(Carthage管理工具)

    一 Carthage项目管理工具使用 Step 1 安装 更新Homebrew工具 1 usr bin ruby e curl fsSL https raw githubusercontent com Homebrew install ma
  • iOS架构师_SDWebImage源码分析

    1 对SDdemo的分析 针对SD的3 8 2版本进行分析 因为从git上面直接下载SD的源码 项目运行会报错 缺少libwebp这个库 我们下载3 8 2版本 运行 libwebp 是个webp的图片格式 属于谷歌的库 所以只能翻墙去国外
  • iOS自动化布局-AutoLayout约束优先级

    约束的优先级 AutoLayout添加的约束中也有优先级 Priority 优先级的数值1 1000 分为两种情况 一种情况是我们经常添加的各种约束 默认值1000 最大值 优先执行 条件允许的话系统会自动满足我们的约束需求 第二种就是固有
  • Objective-C实现链式编程语法(DSL)

    您越着急开始写代码 代码就会花费越长的时间 Carlson University of Wisconsin 前言 熟悉Objective C这一门编程语言的人都知道 Objective C中方法的调用都是通过中括号 实现的 比如 self
  • iOS进阶_密码学(二.钥匙串访问)

    网络开发中的原则 在网络上不允许传输用户的明文隐私数据 在本地不允许保存用户的明文隐私数据 类似于QQ 微信的记住密码 在客户端本地保存用户加密后的密码 NSUserDefaults 明文保存才能反算 能够反算的算法 钥匙串访问 开放给开发
  • iOS进阶_NSURLConnection(被弃用的原因:Connection的缺点)

    NSURLConnection下载 我们在前面的文章中介绍了MAC电脑搭建Apache服务器 在Sites文件夹中放置一个视频文件MVVM mp4 pbb 通过NSURLConnection进行下载 访问http localhost 我们可
  • iOS开发之ReactiveCocoa框架(RAC)第五篇队列与高级函数

    h文件 import ViewController h import ReactiveCocoa interface ViewController end implementation ViewController void viewDid
  • iOS进阶_密码学进阶(三.非对称加密算法-RSA公钥私钥的生成)

    应用场景 集成支付宝SDK 会看见 p12文件也有 非对称加密算法 一 运行终端 生成私钥 1 cd Users mac Desktop iOS 加密 2 openssl genrsa out private pem 512 生成私钥 注意
  • iOS开发 多线程的高级应用-信号量semaphore

    在iOS开发的道路上 多线程的重要性不言而喻 大部分我们都停留在基础的使用上面 缺乏高级应用 缺乏提升 是因为我们面对他太少 复杂的事情重复做 复杂的事务基础化 差距就是这样拉开了 言归正传 今天讲讲GCD的高级应用之信号量篇 一 信号量的
  • iOS进阶_kvc使用注意事项

    细节1 我们在项目中使用kvc 在设置model属性的时候 注意尽量不要使用基本数据类型 实例 数据模拟 注意age是null类型的 Person h import
  • iOS架构-组件化(项目框架搭建2)

    静态库引用静态库 如果像上图一样 直接在业务层组件引用数据层组件的文件 则会报错 因为组件之间没有建立引用关系 如下图 静态库如何引用Pods第三方库 拷贝Podfile文件到项目 打开终端执行pad install 直接引用Pod下面的Y

随机推荐

  • WPF中判断滚动条滚动条滑倒了最底端

    先是获取滚动条的方法 可以获取到空间内部自带的ScrollViewer region 获取所有控件子级元素的方法 返回该类型的List集合 public static List
  • 自己写不出代码我该怎么办

    在作业和练习中 自己写不出代码 这是一个在学习中经常出现的问题 那么该怎么解决这个问题呢 1 先分析实现的思路 拿到作业 按照要实现的功能 先分析去实现的思路 如果完全不知到该怎么去实现 完全是一头雾水 那最好就先看看其他人是如何实现的 或
  • simulink的模块封装与解封装

    MATLAB Simulink 使用技巧 模块封装 简单 1 新建或者打开Simulink仿真环境 2 选择需要封装的部分 单击鼠标右键选择 create subsystem 选项即可封装模块 MATLAB Simulink 使用技巧 模块
  • 在微信小程序中 使用uView rules 表单校验 validator 不起作用(无效)

    注意 如果需要兼容微信小程序 最好通过setRules方法设置rules规则 onReady 如果需要兼容微信小程序 并且校验规则中含有方法等 只能通过setRules方法设置规则 this refs form1 setRules this
  • Sublime4如何自定义代码补全内容

    1 先进入如下文件夹 2 这里举C 为例子 其他语言类似 创建C 文件夹 并在C 文件夹内创建Snippets文件夹 3 在Snippets文件夹下创建以 sublime snippet为后缀的文件 4 在文件中自定义代码补全的信息
  • vue 在style标签中使用变量

    1 定义变量 export default data return 背景y颜色 backgroundColor 00f 字体颜色 fontColor f00 2 在HTML中设置CSS使用的变量
  • [深入研究4G/5G/6G专题-22]: 5G NR开机流程3.4 - MAC层对SIB1的调度 - SIB1消息的格式与内容

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 前置条件 第1章 SIB1消息的格式 内容解析
  • Android sqlite常见sql语句

    创建一个测试表man select from man 查询man表所有信息 select from man where name like 四 删除操作 delete from man where name lucy2 部分字段查询 sel
  • java.sql.SQLException: The user specified as a definer (‘combined‘@‘%‘) does not exist

    java sql SQLException The user specified as a definer combined does not exist 今天我把公司的项目拷回来处理一些遗留的问题 文明的我 爆了粗口TMD 罪过罪过 话不
  • React中高阶组件、Render props、hooks

    这三者都是react中解决代码复用的主要方式 1 HOC 在官方解释中 高阶组件 HOC 是 React 中复用组件逻辑的一种高级技巧 HOC自身不是 React API 的一部分 它是一种基于 React 的组合特性而形成的一种设计模式
  • springCloud整合 Hystrix熔断器(配置)

    springCloud整合 Hystrix熔断器 文章目录 springCloud整合 Hystrix熔断器 前言 一 添加Hystrix依赖 二 properties文件开启熔断器 三 为调用另一个服务的接口添加实现类 前言 在分布式环境
  • Qt Installer Framework使用教程:

    步骤一 下载并安装Qt Installer Framework工具 http download qt io official releases qt installer framework 将安装目录添加到环境变量 如安装D盘时D Qt Q
  • 狂神说 MyBatis 笔记

    这里写目录标题 Mybatis 1 简介 1 1 什么是MyBaits 1 2 持久话 1 3 持久层 1 4 为什么需要Mybatis 2 第一个Mybatis程序 2 1 搭建环境 2 2 创建一个模块 2 3 编写代码 2 4 测试
  • 二分插入排序(c语言)

    一 什么是二分插入排序 二分法插入排序 简称二分排序 是在插入第i个元素时 对前面的0 i 1元素进行折半 先跟他们中间的那个元素比 如果小 则对前半再进行折半 否则对后半进行折半 直到left
  • <02-01-01> Spring IoC容器与Bean介绍(Introduction to the Spring IoC Container and Beans)

    上一篇 02 01 控制反转容器 The IoC Container 本章介绍了Spring 框架对控制反转 Inversion of Control IoC 设计原则的实现 IoC也被称为依赖注入 Dependency Injection
  • SpringBoot配置多个mysql数据源

    当我们在进行数据库分库分表操作是可能会需要到多个数据库 那么我们就需要对多个数据库的数据源进行配置 整理一下 今天在SpringBoot框架下多个数据源的配置过程 两个为例 1 配置数据库信息 在yml配置文件中配置需要的数据库信息 spr
  • 分布式理论基础:CAP和BASE

    CAP定理 分区 在分布式系统中 不同的节点分布在不同的子网络中 由于一些特殊的原因 这些子节点之间出现了网络不通的状态 但他们的内部子网络是正常的 从而导致了整个系统的环境被切分成了若干个孤立的区域 这就是分区 CAP定理 CAP原则又称
  • opencv-python中 boundingRect(cnt)以及cv2.rectangle用法

    转自 http blog csdn net zhangxb35 article details 47275277 矩形边框 Bounding Rectangle 是说 用一个最小的矩形 把找到的形状包起来 还有一个带旋转的矩形 面积会更小
  • 实用常识

    WolframAlpha是开发计算数学应用软件的沃尔夫勒姆 Wolfram 研究公司基于科学计算软件Mathematica开发出的新一代的搜索引擎 试图挑战Google搜索引擎的地位 能根据问题直接给出标准化答案的网站 比如输入一种材料名称
  • iOS开发 多线程的高级应用-信号量semaphore

    在iOS开发的道路上 多线程的重要性不言而喻 大部分我们都停留在基础的使用上面 缺乏高级应用 缺乏提升 是因为我们面对他太少 复杂的事情重复做 复杂的事务基础化 差距就是这样拉开了 言归正传 今天讲讲GCD的高级应用之信号量篇 一 信号量的