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体系非常的庞大和复杂, ...
随机推荐
- ruby -- 基础学习(二) 外键配置实现级联删除
该系列学习基于rails4.0 数据表:admins (id, name, address), articles (id, admin_id, title) admin_id 是表articles中的 ...
- 关于Expression表达式树的拼接
最近在做项目中遇到一个问题,需求是这样的: 我要对已经存在的用户进行检索,可以根据用户的id 或者用户名其中的一部分字符来检索出来,这样就出现了三种情况 只有id,只有用户名中一部字符,或者全部都有. ...
- url rewrite优化url的可读性
1.下载urlrewrite,官方下载地址:http://tuckey.org/urlrewrite/ 2.解压缩文件,将jar放入项目,并创建urlrewrite.xml: 3.将filter添加到 ...
- 【Git】基本命令使用
init: 1 git init 添加远程分支: 1 git remote add <远程主机名> <远程主机地址url> 例如:git remote add origin ...
- selenium webdriver (python) 第三版
感谢 感谢购买第二版的同学,谢谢你们对本人劳动成果的支持!也正是你们时常问我还出不出第三版了,也是你们的鼓励,让我继续学习整理本文档. 感谢乙醇前辈,第二版的文档是放在他的淘宝网站上卖的,感谢他的帮忙 ...
- IT人的自我导向型学习:学习的3个维度
看到大家对我的文章赞了不少,看来大家还比较喜欢看.园子里的一些朋友和我说:”终于又看到你要在园子里发原创文章了.几年前就受益匪浅,经过几年的成长分享来的东西肯定也是精品.“ 感谢大家对我的信任,如果你 ...
- 【Spark】---- 在Linux集群上安装和配置Spark
1 安装JDK 1) 进入JDK官网 2) 下载JDK安装包 3)配置环境变量,在/etc/profile增加以下代码 JAVA_HOME=/home/hadoop/jdk1.6.0_38 PAT ...
- ok6410 android driver(9)
In this essay, I will write the JNI to test our leds device. If you don't know how to create a jni p ...
- Winform里面的缓存使用
缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存 ...
- HTML5 Wijmo:控制 Wijmo Grid 插件的编辑模式
Wijmo jQuery 插件经常应用于在财务类网站中创建平滑和良好用户体验的交互表格.WijGrid 插件用于显示.排序.分组和编辑数据.今天我们来分享下如何控件WijGrid插件的编辑模式. 在本 ...