GCD中的dispatch_semaphore的语法与作用
(一)引入问题
当并行执行的处理更新数据时,会产生数据不一致的情况,有时应用程序还会异常结束,虽然使用Serial Dipatch queue和dispatch_barrier_async函数可避免这类问题,但有必要进行更加细腻的排他控制
/*!
* @brief 不考虑顺序,将所有数据添加到数组中
*/
- (void)testError {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); NSMutableArray *mArray = [NSMutableArray array];
//当执行次数过大时,异常结束的概率很高
for (int i = ; i < ; i++) { dispatch_async(queue, ^{ [mArray addObject:[NSNumber numberWithInt:i]];
});
}
NSLog(@"%@", mArray);
/*!
* @brief 运行结果
*semaphore测试(3312,0x11ab21000) malloc: *** error for object 0x7f971c047000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
* @return 异常结束
*/
}
(二)什么是dispatch_semaphore
dispatch_semaphore是持有计数的信号,该计数是多线程编程中的计数类型信号,类似于过马路的信号灯,红灯表示不能通过,而绿灯表示可以通过
而在dispatch_semaphore中使用计数来实现该功能,进行更细粒度的排他控制.
在没有Serial Dispatch Queue和dispatch_barrier_async函数那么大的粒度且一部分处理需要进行排他控制的情况下,dispatch Semaphore便可发挥威力
(三)dispatch_semaphore语法说明
<1>通过dispatch_semaphore_create(long value);函数创建Dispatch_Semaphore,参数表示计数的初始值
//参数说明
//long value:表示计数的初始值
dispatch_semaphore_t semaphore = dispatch_semaphore_create(long value);
<2>dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);函数等待Dispatch Semaphore的计数值大于或者等于1,当满足条件时计数器执行减法,并从wait函数中返回
***当dispatch_semaphore_wait函数返回0时,可以安全地执行排他控制的处理
//参数说明
//dispatch_semaphore_t dsema:操作的Dispatch_Semaphore对象
//dispatch_time_t timeout:由dispatch_time_t类型值指定等待时间
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
<3>dispatch_semaphore_signal(dispatch_semaphore_t dsema);函数将Dispatch_Semaphore的计数器加1
//参数说明
//dispatch_semaphore_t dsema:操作的Dispatch_Semaphore对象
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
(三)代码演示
/*!
* @brief 使用Dispatch Semaphore进行排他性控制
*/
- (void)semaphoreSample {
//1.创建全局队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//2.创建dispatch_semaphore_t对象
dispatch_semaphore_t semaphore = dispatch_semaphore_create();
//3.创建保存数据的可变数组
NSMutableArray *mArray = [NSMutableArray array];
//执行10000次操作
for (int i = ; i < ; i++) {
//异步添加数据
dispatch_async(queue, ^{
//数据进入,等待处理,信号量减1
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//处理数据
[mArray addObject:[NSNumber numberWithInt:i]];
//数据处理完毕,信号量加1,等待下一次处理
dispatch_semaphore_signal(semaphore);
});
} NSLog(@"%@", mArray); /*!
* @brief 执行结果
*
1
2
3
...
9999
* @return 顺序输出,不会异常结束
*/
}
GCD中的dispatch_semaphore的语法与作用的更多相关文章
- GCD中的dispatch_apply的用法及作用
GCD中的dispatch_apply的用法及作用 (一)dispatch_apply的基本用法 dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联A ...
- GCD中的dispatch_set_target_queue的用法及作用
(一),使用dispatch_set_target_queue更改Dispatch Queue的执行优先级 dispatch_queue_create函数生成的DisPatch Queue不管是Ser ...
- 详解jquery插件中(function ( $, window, document, undefined )的作用。
1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...
- 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序
如何在Visual Studio 2017中使用C# 7+语法 前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...
- bootstrap中table的colspan不起作用
bootstrap中table的colspan不起作用,即在不指定宽度的条件下,各个td宽度不符合colspan指定的宽度. 添加table0layout:fixed后显示正常. table{ tab ...
- jquery 中的 return false 不起作用
jquery 中的 return false 不起作用 $(".lcId").each(function(e) { if ($(this).attr("checked& ...
- iOS 关于GCD中的队列
GCD中队列分类及获得方式 1.串行队列 dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...
- GCD中使用dispatch_after函数延迟处理任务
在实际的开发中,经常会遇到想要在指定的时间间隔后执行某个处理 <一>在GCD中提供了dispatch_after函数来完成这一操作 dispatch_after(dispatch_time ...
- spring中的BeanFactory与ApplicationContext的作用和区别?
BeanFactory类关系继承图 1. BeanFactory类结构体系: BeanFactory接口及其子类定义了Spring IoC容器体系结构,由于BeanFactory体系非常的庞大和复杂, ...
随机推荐
- andriod手机签到应用服务器设计
最近导师要求我和另一个同学开发一个手机上课签到应用,我负责客户端和服务器之间的通信架构编写和数据的存储 本人大学四年只用过汇编和C/C++,因此对andriod开发还是一窍不通,花了一个星期写出来了基 ...
- 移动端 ios 长按复制兼容方案
移动端页面,需要复制一段文字码. 在ios中,长按文字区域,默认选中的范围,超出了我长按的文字区域, 把上面的图片和下面的另一个div的文字也给我包含进来了,并不是我想要的! 举个例子: 如下图: 1 ...
- Linux - 文本格式转换
文本文档格式查看 Linux下的文档格式查看方法 cat -A <filename> | grep "^M$", 如果存在^M$字符就是Dos格式. Windows下的 ...
- Linux - 常见Shell文本处理方法
Common Shell Text Processing 珠玉在前,不再赘言. Linux Shell 文本处理工具集锦:http://blog.jobbole.com/99063/ 数据工程师常用的 ...
- #敏捷个人资料# 免费下载 《敏捷个人-认识自我,管理自我 v0.8.pdf》
快乐.高效.平衡,做一个爱学习.有目标.懂生活的影响者. 从今天开始至7月31日,点击http://t.cn/Rv3koHU 免费收到 1000多页的 <敏捷个人-认识自我,管理自我 v0.8. ...
- log4j的一些问题
今天,在学习log4j的时候发现了一点问题,关于level的问题. log4j.rootLogger=error, console, file , fileerror log4j.logger.com ...
- 阅读《深入理解JavaScript定时机制》
鸟哥的这篇<深入理解JavaScript定时机制>从javascript线程角度分析了setTimeout和setInterval两个定时触发器的实现原理. 看完的体验就是主要要记住两点: ...
- 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function
Calculate the Function Problem's Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...
- 创建Google网站地图Sitemap.xml
Sitemap.xml是google搞出来的,也就是网站地图,不过这个网站地图是用xml写的,而且要按google的标准来写,并且要将写出来的这个文件sitemap.xml上传到自己的服务器空间中去. ...
- 以对象的方式来访问xml数据表(二)
为什么要以对象的方式来访问xml数据表? 还记得,自己是在一次完成师兄布置的任务时接触到了xml,那时候需要用xml来作为数据文件,保存一个简单的图书管理系统的数据.于是就知道了,可以用xml文件来保 ...