初探GCD
来源:互联网 发布:八爪鱼采集器的源码 编辑:程序博客网 时间:2024/06/04 18:05
GCD的编程核心是dispatch队列,block是被放到队列中去执行的。你既可以使用系统提供的队列,也可以自己创建队列。队列有串行和并行之分,block可被同步执行或异步执行。这篇博客就简单介绍下串并行,同步异步状态下的block执行结果区别。
大家很容易把同步异步和阻塞非阻塞的概念混淆。同步和异步关注的是消息的通信机制,阻塞和非阻塞关注的是程序在等待(调用)结果时的状态。(这4个概念的详细介绍可以参考点击打开链接)
- 同步:发出调用之后,在没有得到计算结果前就不返回,直到有返回结果为止。(必须等到被调用的函数有了返回值或计算完毕之后,才能够继续执行下面的代码)
- 异步:发出调用之后立即返回,没有得到结果。最后是通过回调函数等来得到结果的。(无需等到被调用函数计算完毕,就可以立即执行后续代码)
串行跟并行就不再啰嗦了,这里只要记住一点即可:加入到串行队列中的block是按照FIFO顺序执行。下面进入正题,串行并行,同步异步相组合block的结果有何不同。
注意:下面代码的执行结果打印时间
- 将block放到串行队列中
<span style="font-size:14px;">dispatch_queue_t queue = dispatch_queue_create("xiao.custom.serial.syn.queue", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ NSLog(@"serial 1 start"); [NSThread sleepForTimeInterval:2]; NSLog(@"serial 1 end"); }); NSLog(@"上面是同步执行,block完毕之后,我才能够得到执行"); dispatch_sync(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"serial 2 end"); }); dispatch_async(queue, ^{ NSLog(@"serial 3 start"); [NSThread sleepForTimeInterval:3]; NSLog(@"serial 3 end"); }); NSLog(@"即使3异步执行也要等到1,2结束才开始,因为3被放到了串行队列,FIFO"); NSLog(@"但是3的执行时间不会影响它下面的代码,你看3睡秒了3秒不是没有影响到我的执行吗");</span><span style="font-size:12px;"></span>
<span style="font-size:14px;">2015-12-04 19:25:41.635 Learn_GCD[3173:1585477] serial 1 start2015-12-04 19:25:43.636 Learn_GCD[3173:1585477] serial 1 end2015-12-04 19:25:43.636 Learn_GCD[3173:1585477] 上面是同步执行,block完毕之后,我才能够得到执行2015-12-04 19:25:47.638 Learn_GCD[3173:1585477] serial 2 end2015-12-04 19:25:47.638 Learn_GCD[3173:1585477] 即使3异步执行也要等到1,2结束才开始,因为3被放到了串行队列,FIFO2015-12-04 19:25:47.638 Learn_GCD[3173:1585631] serial 3 start2015-12-04 19:25:47.638 Learn_GCD[3173:1585477] 但是3的执行时间不会影响它下面的代码,你看3睡秒了3秒不是没有影响到我的执行吗2015-12-04 19:25:50.639 Learn_GCD[3173:1585631] serial 3 end</span>
- 将block放到并行队列中
<span style="font-size:14px;">dispatch_queue_t queue = dispatch_queue_create("xiao.custom.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"concurrent 1 start"); [NSThread sleepForTimeInterval:2]; NSLog(@"concurrent 1 end"); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"concurrent 2 end"); }); dispatch_async(queue, ^{ NSLog(@"concurrent 3 start"); [NSThread sleepForTimeInterval:3]; NSLog(@"concurrent 3 end"); });</span><span style="font-size:18px;"></span>
生成一个并发执行队列,block被分发到多个线程去执行 1,2,3的睡秒时间互不影响 18:57:40.813 Learn_GCD[2931:1500822] 1 start 18:57:40.813 Learn_GCD[2931:1500824] 3 start 18:57:42.814 Learn_GCD[2931:1500822] 1 end 18:57:43.814 Learn_GCD[2931:1500824] 3 end 18:57:44.813 Learn_GCD[2931:1500823] 2 end
<span style="font-size:14px;">dispatch_queue_t queue = dispatch_queue_create("xiao.custom.concurrent.queue2", DISPATCH_QUEUE_CONCURRENT); dispatch_sync(queue, ^{ NSLog(@"concurrent 1 start"); [NSThread sleepForTimeInterval:2]; NSLog(@"concurrent 1 end"); }); dispatch_sync(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"concurrent 2 end"); }); dispatch_sync(queue, ^{ NSLog(@"concurrent 3 start"); [NSThread sleepForTimeInterval:3]; NSLog(@"concurrent 3 end"); });</span><span style="font-size:18px;"></span>
<span style="font-size:14px;">生成一个并发执行队列,block被分发到多个线程去执行 因为是同步执行,所以即使被分发到多个线程,也要等到上一个block返回之后下一个才能执行 2015-12-04 19:31:21.546 Learn_GCD[3199:1599520] concurrent 1 start 2015-12-04 19:31:23.547 Learn_GCD[3199:1599520] concurrent 1 end 2015-12-04 19:31:27.548 Learn_GCD[3199:1599520] concurrent 2 end 2015-12-04 19:31:27.548 Learn_GCD[3199:1599520] concurrent 3 start 2015-12-04 19:31:30.549 Learn_GCD[3199:1599520] concurrent 3 end</span><span style="font-size:18px;"></span>
再来看看这段代码为什么会出现死锁
dispatch_queue_t queue = dispatch_queue_create("xiao.custom.serial.queue2", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ dispatch_sync(queue, ^{ }); });
block被放到串行队列中,同步执行。
先进入queue的block先执行,这个block里嵌套了一个block并且又是跟它在同一个queue里执行的。后进入queue的block要等到先进入的执行完毕它才能执行(FIFO),它就处在等待状态。而先进入的block也在等它的第一行代码执行完毕之后才能执行之后的代码。故而造成死锁。
0 0
- 初探GCD
- 初探GCD
- Grand Central Dispatch(GCD)初探
- IOS 多线程初探(三) - GCD
- iOS高级面试GCD初探
- iOS开发之GCD(1)初探
- iOS线程初探(四) GCD 和 NSOperation 小结
- gcd
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- 欢迎使用CSDN-markdown编辑器
- LightOJ 1148 - Mad Counting【数学】
- [读取文件数据],open()的返回类型和【list.append(),造成显性写入\n】。方法参数的缺省带来的影响?
- 操作系统进程环境
- js 语法 new function与function
- 初探GCD
- java面试宝典
- HDU1069 Monkey and Banana
- php连接MySQL失败问题解决
- js高级编程-10-DOM
- LeetCode 104:Maximum Depth of Binary Tree
- C#与Java泛型的比较
- 大数乘法——POJ2389
- mysql中select5种子句之limit