IOS 多线程之信号量
在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);
});
}
}
代码讲解如下图:
IOS 多线程之信号量相关推荐
- iOS 多线程:『GCD』详尽总结
原文链接:www.jianshu.com/p/2d57c7201- 感谢大家对这篇文章的喜欢和支持.为了不辜负大家的喜欢,也为了更好的让大家了解 iOS 多线程,以及 GCD 的相关知识,我对这篇文章 ...
- iOS 多线程使用示例
iOS是一款非常流行的移动操作系统,它的多线程特性被广泛应用于各种应用程序中.在本文中,我们将介绍iOS多线程的使用示例,以帮助开发人员更好地理解和应用多线程技术. 多线程概述 在iOS中,多线程是指 ...
- IOS多线程开发详解
概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...
- iOS多线程详解:实践篇
iOS多线程实践中,常用的就是子线程执行耗时操作,然后回到主线程刷新UI.在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于在iOS中除了主线程,其他子线程是独立 ...
- iOS多线程资源共享的控制方法
1. 关于多线程的同步问题 使用多线程有许多我们众所周知的优点,比如响应度高.充分发挥多核处理器的性能等.但是每个线程的创建也都是有一定的成本.线程同步的官方解释 :协同步调,让多个线程按照预定的先 ...
- iOS多线程开发:几个容易被忽略的细节(马甲包)
一般情况下,iOS开发者只要会使用GCD.@synchronized.NSLock等几个简单的API,就可以应对大部分多线程开发了,不过这样是否真正做到了多线程安全,又是否真正充分利用了多线程的效率优 ...
- iOS - 多线程的锁
iOS - 多线程的锁 多线程同时访问同一块资源会造成资源抢夺,容易引发数据错乱和数据安全问题,此时我们需要保证资源同时只有一个线程访问,加锁就是为了解决这个问题. 常用的加锁方式:(性能由差到好) ...
- 「面向打野编程」iOS多线程:CGD
「面向打野编程」iOS多线程:CGD 前言 参考网络其他文章而写,渣水平,抛砖引玉. 虽然Concurrent意思为并发,但由于队列的实际效果,以下称为并行队列. 当前iPhone的CPU核心数远小于 ...
- iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)
2017-07-08 remember17 Cocoa开发者社区 目的 本文主要是分享iOS多线程的相关内容,为了更系统的讲解,将分为以下7个方面来展开描述. 多线程的基本概念 线程的状态与生命周期 ...
最新文章
- 如何实现良好的隔空操作体验
- scrum立会报告+燃尽图(第三周第七次)
- 苹果9是5g手机吗_苹果手机扩容对手机有影响吗
- C# 调用人脸识别 虹软ArcFace2.0实例
- html5 ios cookie,ios – WKWebView,获取所有cookie
- pip intsall 遇到的各种问题
- idea怎么找到路径下面的js_怎么找到Win7桌面存储路径?怎么把Win7桌面转到D盘?...
- 【开发工具】之makefile基本规则
- Android开发学习之快速实现圆角ListView
- 雅礼集训 Day6 T2 Equation 解题报告
- 从移动硬盘安装计算机系统文件,移动硬盘装系统,教您怎么用移动硬盘装系统...
- 【云原生之Docker实战】使用Docker部署siyuan个人笔记系统
- The application bundle does not contain a valid identifier
- 常见python爬虫模板_常见的Python爬虫框架有几个?
- java会变得更简单吗_spring 第一篇(1-1):让java开发变得更简单(下)
- Linux系统下,永久修改海思开发板的IP地址
- 适配mpvue平台的的微信小程序日历组件mpvue-calendar
- 41 ItemsWidget之QListWidget
- 代码整洁之道读书笔记(Ch4-Ch7)
- java8函数式编程笔记-科里化