dispatch_group_t 日常使用注意事项
一、背景简介
平时在进行多线程处理任务时,有时候希望多个任务之间存在着一种联系,希望在所有的任务执行完后做一些总结性处理。
那么就可以将多个任务放在一个任务组中进行统一管理。dispatch提供了相应的API供我们完成这一需求。
二、dispatch_group_t相关属性介绍
1.dispatch_group_async(group, queue, block);
将block任务添加到queue队列,并被group组管理
2.dispatch_group_enter(group);
声明dispatch_group_enter(group)下面的任务由group组管理,group组的任务数+1
3.dispatch_group_leave(group);
相应的任务执行完成,group组的任务数-1
4.dispatch_group_create();
创建一个group组
5.dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
当前线程暂停,等待dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)上面的任务执行完成后,线程才继续执行。
6.dispatch_group_notify(group1, queue1,block);
监听group组中任务的完成状态,当所有的任务都执行完成后,触发block块,执行总结性处理。
三、常见用法的区别
在使用group组处理任务时,常见的有两种组合。
其一:
dispatch_group_async(group, queue, block);
dispatch_group_notify(group1, queue1, block);
在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:
第一种:同步任务时
dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group1 = dispatch_group_create();
dispatch_group_async(group1, queue1, ^{
dispatch_sync(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
}
});
});
dispatch_group_async(group1, queue1, ^{
dispatch_sync(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
}
});
});
// //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
//等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group1, queue1, ^{
NSLog(@"Method1-全部任务执行完成");
});
同步任务运行结果:
-- ::05.883 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::05.884 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] Method1-全部任务执行完成
第二种:异步任务时
dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group1 = dispatch_group_create();
dispatch_group_async(group1, queue1, ^{
dispatch_async(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
}
});
});
dispatch_group_async(group1, queue1, ^{
dispatch_async(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
}
});
});
// //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
//等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group1, queue1, ^{
NSLog(@"Method1-全部任务执行完成");
});
异步任务运行结果:
-- ::28.889 MyTestWorkProduct[:] Method1-全部任务执行完成
-- ::29.893 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::29.893 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::30.896 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::30.896 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::31.901 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::31.901 MyTestWorkProduct[:] 任务1-异步任务执行-:
结论:dispatch_group_async(group, queue, block) 和 dispatch_group_notify(group1, queue1, block) 组合在执行同步任务时正常,在执行异步任务时不正常。
其二
dispatch_group_enter(group);
dispatch_group_leave(group);
dispatch_group_notify(group1, queue1,block);
在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:
第一种:同步任务时
dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group2 = dispatch_group_create();
dispatch_group_enter(group2);
dispatch_sync(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
}
dispatch_group_leave(group2);
});
dispatch_group_enter(group2);
dispatch_sync(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
}
dispatch_group_leave(group2);
});
// //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
//等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group2, queue2, ^{
NSLog(@"Method2-全部任务执行完成");
});
同步任务执行结果:
-- ::05.884 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::08.887 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::09.888 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::10.889 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::10.889 MyTestWorkProduct[:] Method2-全部任务执行完成
第二种:异步任务时
dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group2 = dispatch_group_create();
dispatch_group_enter(group2);
dispatch_async(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
}
dispatch_group_leave(group2);
});
dispatch_group_enter(group2);
dispatch_async(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
}
dispatch_group_leave(group2);
});
// //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
//等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group2, queue2, ^{
NSLog(@"Method2-全部任务执行完成");
});
异步任务执行结果:
-- ::38.705 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::38.705 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::39.709 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::39.709 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::40.712 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::40.712 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::40.713 MyTestWorkProduct[:] Method2-全部任务执行完成
结论:
dispatch_group_enter(group)、dispatch_group_leave(group) 和 dispatch_group_notify(group1, queue1,block) 组合在执行同步任务时正常,在执行异步任务时正常。
dispatch_group_t 日常使用注意事项的更多相关文章
- Zookeeper从入门到精通(开发详解,案例实战,Web界面监控)
ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookee ...
- 超详细的HashMap解析(jdk1.8)
目录 一.预备知识 时间复杂度 基本数据结构 基本位运算 二.HashMap实现原理 结构 速度 三.源码分析 基本常量 基本成员变量 构造方法 put方法 remove 四.日常使用注意事项 五.总 ...
- Oracle GoldenGate OGG管理员手册(较早资料)
第一章 系统实现简述 前言 编写本手册的目的是为系统管理员以及相关操作人员提供 Oracle Goldengat 软 件的日常维护和使用的技术参考: 3 ORACLE 第二章 OGG 日常维护操作 ...
- ZooKeeper_基础知识学习
ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookee ...
- Oracle GoldenGate OGG管理员手册
第一章 系统实现简述 前言 编写本手册的目的是为系统管理员以及相关操作人员提供 Oracle Goldengat 软 件的日常维护和使用的技术参考: 3 ORACLE 第二章 OGG 日常维护操作 ...
- 【转】Camera 简介
一.摄像头(CAMERA)又称为电脑相机.电脑眼等,它作为一种视频输入设备,在过去被广泛的运用于视频会议.远程医疗及实时监控等方面. 近年以来,随着互联网技术的发展,网络速度的不断提高,再加上感光成像 ...
- 不可错过的效能利器「GitHub 热点速览 v.22.39」
如果你是一名前端工程师且维护着多个网站,不妨试试本周榜上有名的 HTML-first 的 Qwik,提升网站访问速度只用一招.除了提升网站加载速度的 Qwik,本周周榜上榜的 Whisper 也是一个 ...
- ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- ORACLE分区表梳理系列(一)- 分区表概述、分类、使用方法及注意事项
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
随机推荐
- 2761: [JLOI2011]不重复数字(平衡树)
2761: [JLOI2011]不重复数字 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2133 Solved: 825[Submit][Stat ...
- android开发艺术探索读书笔记之-------view的事件分发机制
View的点击事件的分发,其实就是对MotionEvent事件的分发过程,即当一个MotionEvent产生后,系统需要把这个事件传递给一个具体的View,而这个过程就是分发过程. 分发过程主要由以下 ...
- bootstrap常见类的总结
相信大家和我一样,曾经找过bootstrap的类名定义. 无奈没有找到现成的,那我就来总结一下常见类名吧. 基础样式:btn,alert,form,table,input,select.textare ...
- python中的列表list
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...
- vpn的实现原理
由于公共IP的短缺,我们在组建局域网时,通常使用保留地址作为内部IP,(比如最常用的C类保留地址:192.168.0.0-192.168.255.255)这些地址是不会被互联网分配的,因此它们在互联网 ...
- Java字节流在Android中的使用
引言:项目开发有时会使用上传文件到服务器,再从服务器取数据显示到本地这一过程:或者输入一段文字,再把文字显示出来.这个过程都用到了IO流. IO流分为字符流(Reader\Writer)和字节流(In ...
- Spring初识(通过小实例清晰认识Spring)
1.spring架构: spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,iba ...
- 转载 webstrom识别 React语法
对于程序员而言:驼峰和下划线之间是一场宗派战争:大括号是否换行会成为一种党派:逗号写在行尾还是行首的人来自不同星球-- 然而,无规矩不成方圆,任何一个团队,要想有高质量的产出,第一步必须要对一些基本的 ...
- express创建网站
Express 在初始化一个项目的时候需要指定模板引擎,默认支持Jade和ejs. 这里我们使用ejs模板引擎:(关于ejs的介绍可以先从百科里面了解一个大概)EJS是一个JavaScript模板库, ...
- centOS下调整swap
[root@localhost /]# mkdir swap [root@localhost /]# cd swap [root@localhost swap]# dd if=/dev/zero of ...