GCD收录3--dispatch_group线程调度组
来源:互联网 发布:cms监控软件客户端下载 编辑:程序博客网 时间:2024/06/05 23:49
一、简单介绍下将会用到的一些东西
英语不好就不翻译官方文档了..
1、dispatch_group_async
Submits a block to a dispatch queue and associates the block with the given dispatch group//将一个block(代码块)加入到dispatch_queue_t queue中并和dispatch_group_t group相关联voiddispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);
个人理解:将代码块dispatch_block_t block放入队列dispatch_queue_t queue中执行;并和调度组dispatch_group_t group相互关联;如果提交到dispatch_queue_t queue中的block全都执行完毕会调用dispatch_group_notify并且dispatch_group_wait会停止等待;
2、dispatch_group_enter(group)、dispatch_group_leave(group)
Calling this function indicates another block has joined the group through a means other than dispatch_group_async(). Calls to this function must be * balanced with dispatch_group_leave().调用这个方法标志着一个代码块被加入了group,和dispatch_group_async功能类似;需要和dispatch_group_enter()、dispatch_group_leave()成对出现;voiddispatch_group_enter(dispatch_group_t group);
个人理解:和内存管理的引用计数类似,我们可以认为group也持有一个整形变量(只是假设),当调用enter时计数加1,调用leave时计数减1,当计数为0时会调用dispatch_group_notify并且dispatch_group_wait会停止等待;
3、dispatch_group_notify
voiddispatch_group_notify(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);个人理解:当提交到队列dispatch_queue_t queue上的所有任务执行完毕时会执行dispatch_group_notify里的dispatch_block_t block的代码
4、dispatch_group_wait
longdispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);个人理解:和dispatch_group_notify功能类似(多了一个dispatch_time_t参数可以设置超时时间),在group上任务完成前,dispatch_group_wait会阻塞当前线程(所以不能放在主线程调用)一直等待;当group上任务完成,或者等待时间超过设置的超时时间会结束等待;
二、dispatch_group_async代码示例
- (void)groupSync{ dispatch_queue_t disqueue = dispatch_queue_create("com.shidaiyinuo.NetWorkStudy", DISPATCH_QUEUE_CONCURRENT); dispatch_group_t disgroup = dispatch_group_create(); dispatch_group_async(disgroup, disqueue, ^{ NSLog(@"任务一完成"); }); dispatch_group_async(disgroup, disqueue, ^{ sleep(8); NSLog(@"任务二完成"); }); dispatch_group_notify(disgroup, disqueue, ^{ NSLog(@"dispatch_group_notify 执行"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_group_wait(disgroup, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); NSLog(@"dispatch_group_wait 结束"); });}
向group中放入两个任务(准确讲是将任务加入到了并行队列disqueue中执行,然后队列和group关联当队列上任务执行完毕时group会进行同步),第二个任务会等待8秒所以第一个任务会先完成;会先打印任务一完成再打印任务二完成,当两个任务都完成时dispatch_group_notify中的block会执行;会接着打印dispatch_group_notify 执行;dispatch_group_wait设置了超时时间为5秒所以它会在5秒后停止等待打印dispatch_group_wait 结束(任务二会等待8秒所以它会在任务二完成前打印);
需要注意的:dispatch_group_wait是同步的所以不能放在主线程执行。
补充: dispatch_group会等和它关联的所有的dispatch_queue_t上的任务都执行完毕才会发出同步信号(dispathc_group_notify的代码块block会被执行,group_wati会结束等待)。也就是说一个group可以关联多个任务队列;下面给出示例:
- (void)groupSync2{ dispatch_queue_t dispatchQueue = dispatch_queue_create("ted.queue.next1", DISPATCH_QUEUE_CONCURRENT); dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0); dispatch_group_t dispatchGroup = dispatch_group_create(); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ sleep(5); NSLog(@"任务一完成"); }); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ sleep(6); NSLog(@"任务二完成"); }); dispatch_group_async(dispatchGroup, globalQueue, ^{ sleep(10); NSLog(@"任务三完成"); }); dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){ NSLog(@"notify:任务都完成了"); });}
上面的代码里有两个队列一个是我自己创建的并行队列dispatchQueue,另一个是系统提供的并行队列globalQueue;dispatch_group_notify会等这两个队列上的任务都执行完毕才会执行自己的代码块。
三、dispatch_group_enter、dispatch_group_level示例
和dispatch_async相比,当我们调用n次dispatch_group_enter后再调用n次dispatch_group_level时,dispatch_group_notify和dispatch_group_wait会收到同步信号;这个特点使得它非常适合处理异步任务的同步当异步任务开始前调用dispatch_group_enter异步任务结束后调用dispatch_group_leve;
下面是代码示例:
- (void)groupSync{ dispatch_group_t group = dispatch_group_create(); dispatch_group_enter(group); dispatch_async(dispatch_get_global_queue(0, 0), ^{ sleep(5); NSLog(@"任务一完成"); dispatch_group_leave(group); }); dispatch_group_enter(group); dispatch_async(dispatch_get_global_queue(0, 0), ^{ sleep(8); NSLog(@"任务二完成"); dispatch_group_leave(group); }); dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务完成"); });}
示例代码中在global_queue上执行sleep任务模拟网络请求。
补充: 如果像最后一个示例那样,block里执行的是同步类型的代码那么用dispatch_group_async一样可以达到同步的效果,但是异步任务就不行了如下:
- (void)groupSync2{ dispatch_queue_t dispatchQueue = dispatch_queue_create("ted.queue.next1", DISPATCH_QUEUE_CONCURRENT); dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0); dispatch_group_t dispatchGroup = dispatch_group_create(); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ dispatch_async(globalQueue, ^{ sleep(5); NSLog(@"任务一完成"); }); }); dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ dispatch_async(globalQueue, ^{ sleep(8); NSLog(@"任务二完成"); }); }); dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){ NSLog(@"notify:任务都完成了"); });}
如果dispatch_group_async里执行的是异步代码dispatch_group_notify会直接触发而不会等待异步任务完成,而dispatch_group_enter、和dispatch_group_leave则不会有这个问题,它们只需要在任务开始前enter结束后leave即可达到线程同步的效果。
作者:liang1991
链接:http://www.jianshu.com/p/228403206664
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- GCD收录3--dispatch_group线程调度组
- GCD(三) ---- dispatch_group 调度群组
- GCD(dispatch_group)
- GCD-dispatch_group
- iOS系统GCD学习(3):dispatch_group
- iOS系统GCD学习(3):dispatch_group
- iOS系统GCD学习(3):dispatch_group
- iOS系统GCD学习(3):dispatch_group
- iOS--GCD(使用dispatch_group来进行线程同步)
- GCD(四)dispatch_group
- GCD 学习(四) dispatch_group
- GCD 学习(四) dispatch_group
- GCD 第三篇 dispatch_group
- ios 多线程控制线程并发数、GCD之dispatch_group、GCD信号量
- GCD高级用法(二) dispatch_group
- iOS开发之GCD -- dispatch_group
- iOS开发:深入理解GCD 第二篇(dispatch_group、dispatch_barrier、基于线程安全的多读单写)
- iOS开发:深入理解GCD 第二篇(dispatch_group、dispatch_barrier、基于线程安全的多读单写)
- 层次聚类算法java实现
- 谈《与神对话》中,你最高的真实隐…
- 转:锁的优化和注意事项
- NLTK07《Python自然语言处理》code06 学习分类文本
- BZOJ 题目整理
- GCD收录3--dispatch_group线程调度组
- Scala中package与import实战详解
- 梯度下降法
- Android图片加载框架最全解析(五),Glide强大的图片变换功能
- 微信公众号支付开发全过程 --JAVA
- ffmpeg 中print_report中相关日志说明
- FSN (dp)
- 小结
- Android双击屏幕动态实现全屏(隐藏标题栏状态栏)