(一)引入问题

当并行执行的处理更新数据时,会产生数据不一致的情况,有时应用程序还会异常结束,虽然使用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的语法与作用的更多相关文章

  1. GCD中的dispatch_apply的用法及作用

    GCD中的dispatch_apply的用法及作用 (一)dispatch_apply的基本用法 dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联A ...

  2. GCD中的dispatch_set_target_queue的用法及作用

    (一),使用dispatch_set_target_queue更改Dispatch Queue的执行优先级 dispatch_queue_create函数生成的DisPatch Queue不管是Ser ...

  3. 详解jquery插件中(function ( $, window, document, undefined )的作用。

    1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...

  4. 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序

    如何在Visual Studio 2017中使用C# 7+语法   前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...

  5. bootstrap中table的colspan不起作用

    bootstrap中table的colspan不起作用,即在不指定宽度的条件下,各个td宽度不符合colspan指定的宽度. 添加table0layout:fixed后显示正常. table{ tab ...

  6. jquery 中的 return false 不起作用

    jquery  中的 return false 不起作用 $(".lcId").each(function(e) { if ($(this).attr("checked& ...

  7. iOS 关于GCD中的队列

    GCD中队列分类及获得方式 1.串行队列  dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...

  8. GCD中使用dispatch_after函数延迟处理任务

    在实际的开发中,经常会遇到想要在指定的时间间隔后执行某个处理 <一>在GCD中提供了dispatch_after函数来完成这一操作 dispatch_after(dispatch_time ...

  9. spring中的BeanFactory与ApplicationContext的作用和区别?

    BeanFactory类关系继承图 1. BeanFactory类结构体系: BeanFactory接口及其子类定义了Spring IoC容器体系结构,由于BeanFactory体系非常的庞大和复杂, ...

随机推荐

  1. ArcGIS如何将表连接到空间数据上

    当我们有一些空间数据和一些业务数据(表),希望把业务数据和空间数据连接起来时,可以采用ArcGIS Desktop进行操作.本文将介绍如何在ArcGIS Destop中将表和空间数据关联起来. Arc ...

  2. js实现无刷新表单提交文件,将ajax请求转换为form请求方法

    最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...

  3. NOP登录验证管理

    截取Nop登录代码如下: 其实 public ActionResult Login(LoginModel model, string returnUrl, bool captchaValid) { / ...

  4. jqmobile小技巧

    jqmobile API好像是不全,很多查不到.记录下自己的发现: 1.popup:data-position-to能够指向class或者id:data-position-to="#id|| ...

  5. 通过Nginx实现负载均衡

    百度了下负载均衡:英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器.企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务 嗯,跟我理 ...

  6. jdbc中的细节

    JDBC 架构:JDBC 的 API 支持两层和三层处理模式进行数据库的访问,但是一般的JDBC架构由两层处理模式组成.(1)JDBC API:提供了应用程序对 JDBC 管理器的连接(2)JDBC ...

  7. Scrum团队

    5.Scrum团队成立 5.1 团队名称,团队目标.团队口号.团队照: 团队名称:@four! 团队目标:做出像“数学口袋精灵”那么棒的软件 团队口号:多劳多得 团队照: 5.2 角色分配 产品负责人 ...

  8. Scrum 项目1.0 2.0 3.0 4.0 5.0 6.0 7.0

    1.确定选题. 应用NABCD模型,分析你们初步选定的项目,充分说明你们选题的理由. 录制为演说视频,上传到视频网站,并把链接发到团队博客上. 截止日期:2016.5.6日晚10点 阅读教材第8章,8 ...

  9. Sql Server来龙去脉系列之二 框架和配置

    本节主要讲维持数据的元数据,以及数据库框架结构.内存管理.系统配置等.这些技术点在我们使用数据库时很少接触到,但如果要深入学习Sql Server这一章节也是不得不看.本人能力有限不能把所有核心的知识 ...

  10. win8.1安装开发工具vs2013.3+mssql2012全程

    几个常用的命令 重起计算机命令:shoutdown.exe -r -t 0 立刻重起 在远程桌面中没有关机重起的选项,这个命令是必须的 远程桌面连接:mstsc 硬件环境:I7 4770 64RAM ...