GCD 之串行、并行
2016-02-24 09:52
141 查看
GCD为我们提供了三种类型的调度队列(dispatch queue),分别为串行,并行和主调度队列。
你可以创建任意个数的串行队列,每个队列依次执行添加的任务,一个队列同一时刻只能执行一个任务(串行),但是各个队列之间不影响,可以并发执行。每个队列中的任务运行在一个由各自串行队列维护的独立线程上,一个队列中只有一个线程。
下面,我将创建一个串行队列,添加两个任务,来演示串行执行的过程。
运行得到结果1:
2012-05-14 18:45:01.766 GDCDemo[389:f803] taskfirst 已经加入队列
2012-05-14 18:45:01.766 GDCDemo[389:11103] taskFirst 任务开始执行
2012-05-14 18:45:01.767 GDCDemo[389:f803] tasksecond 已经加入队列
2012-05-14 18:45:01.768 GDCDemo[389:11103] taskFirst 任务结束
2012-05-14 18:45:01.768 GDCDemo[389:11103] taskSecond任务开始执行
2012-05-14 18:45:01.772 GDCDemo[389:11103] taskSecond 任务结束
运行结果跟我们的预计一样,taskFirst执行完之后,才执行taskSecond。而且,通过“xxx任务加入队列”的提示,任务运行的线程跟主线程不是同一个。
下面,我们继续对代码做点调整,让它演示不同队列之间的任务并行运行。
运行得到结果2:
2012-05-14 19:07:22.951 GDCDemo[456:f803] taskfirst 已经加入队列
2012-05-14 19:07:22.951 GDCDemo[456:11103] taskFirst 任务开始执行
2012-05-14 19:07:22.953 GDCDemo[456:f803] tasksecond 已经加入队列
2012-05-14 19:07:22.953 GDCDemo[456:12c03] taskSecond任务开始执行
2012-05-14 19:07:22.954 GDCDemo[456:12c03] taskSecond 任务结束
2012-05-14 19:07:22.977 GDCDemo[456:11103] taskFirst 任务结束
由此可见,taskSecond是添加到队列后立即执行的。两个串行队列之间的任务是互不影响的。
下面,我们将上一个程序的第21到28行替换为如下代码:
运行,结果与结果2相同。说明了,taskFirst和taskSecond是同时运行的。
演示代码如下:
dispatch_async(dispatch_get_main_queue(),
^{
.....//跟新界面的操作
});
串行(Serial)
你可以创建任意个数的串行队列,每个队列依次执行添加的任务,一个队列同一时刻只能执行一个任务(串行),但是各个队列之间不影响,可以并发执行。每个队列中的任务运行在一个由各自串行队列维护的独立线程上,一个队列中只有一个线程。下面,我将创建一个串行队列,添加两个任务,来演示串行执行的过程。
1 UInt32 loopCount = 1000; 2 3 void (^taskFirst)(void) = ^{ 4 NSLog(@"taskFirst 任务开始执行\r\n"); 5 6 for (UInt32 i = 0; i < loopCount; i++) { 7 8 } 9 NSLog(@"taskFirst 任务结束\r\n"); 10 }; 11 12 void (^taskSecond)(void) = ^{ 13 NSLog(@"taskSecond任务开始执行\r\n"); 14 for (UInt32 i = 0; i < loopCount; i ++) { 15 16 } 17 NSLog(@"taskSecond 任务结束\r\n"); 18 }; 19 dispatch_queue_t serialQueue; 20 serialQueue = dispatch_queue_create("serialDemo", NULL); 21 dispatch_async(serialQueue, taskFirst); 22 NSLog(@"taskfirst 已经加入队列\r\n"); 23 dispatch_async(serialQueue, taskSecond); 24 NSLog(@"tasksecond 已经加入队列\r\n");
运行得到结果1:
2012-05-14 18:45:01.766 GDCDemo[389:f803] taskfirst 已经加入队列
2012-05-14 18:45:01.766 GDCDemo[389:11103] taskFirst 任务开始执行
2012-05-14 18:45:01.767 GDCDemo[389:f803] tasksecond 已经加入队列
2012-05-14 18:45:01.768 GDCDemo[389:11103] taskFirst 任务结束
2012-05-14 18:45:01.768 GDCDemo[389:11103] taskSecond任务开始执行
2012-05-14 18:45:01.772 GDCDemo[389:11103] taskSecond 任务结束
运行结果跟我们的预计一样,taskFirst执行完之后,才执行taskSecond。而且,通过“xxx任务加入队列”的提示,任务运行的线程跟主线程不是同一个。
下面,我们继续对代码做点调整,让它演示不同队列之间的任务并行运行。
1 UInt32 loopCount = 1000; 2 UInt32 loopCountFirst = 10000000; 3 4 void (^taskFirst)(void) = ^{ 5 NSLog(@"taskFirst 任务开始执行\r\n"); 6 7 //延长taskFirst的运行时间 8 for (UInt32 i = 0; i < loopCountFirst; i++) { 9 10 } 11 NSLog(@"taskFirst 任务结束\r\n"); 12 }; 13 14 void (^taskSecond)(void) = ^{ 15 NSLog(@"taskSecond任务开始执行\r\n"); 16 for (UInt32 i = 0; i < loopCount; i ++) { 17 18 } 19 NSLog(@"taskSecond 任务结束\r\n"); 20 }; 21 dispatch_queue_t serialQueue; 22 serialQueue = dispatch_queue_create("serialDemo", NULL); 23 //创建第二个队列 24 dispatch_queue_t serialQueueSecond = dispatch_queue_create("serialSecondDemo", NULL); 25 dispatch_async(serialQueue, taskFirst); 26 NSLog(@"taskfirst 已经加入队列\r\n"); 27 dispatch_async(serialQueueSecond, taskSecond); 28 NSLog(@"tasksecond 已经加入队列\r\n");
运行得到结果2:
2012-05-14 19:07:22.951 GDCDemo[456:f803] taskfirst 已经加入队列
2012-05-14 19:07:22.951 GDCDemo[456:11103] taskFirst 任务开始执行
2012-05-14 19:07:22.953 GDCDemo[456:f803] tasksecond 已经加入队列
2012-05-14 19:07:22.953 GDCDemo[456:12c03] taskSecond任务开始执行
2012-05-14 19:07:22.954 GDCDemo[456:12c03] taskSecond 任务结束
2012-05-14 19:07:22.977 GDCDemo[456:11103] taskFirst 任务结束
由此可见,taskSecond是添加到队列后立即执行的。两个串行队列之间的任务是互不影响的。
并行(Concurrent)
并行队列是不允许自己创建的,系统中存在三个不同优先级的并行队列。并行队列依旧按照任务添加的顺序启动任务,但是,后一个任务无须等待前一个任务执行完毕,而是启动第一个任务后,立即启动下一个任务。至于同一时刻允许同时运行多少个任务有系统决定。任务各自运行在并行队列为他们提供的独立线程上,并行队列中同时运行多少个任务,就必须维护多少个线程。下面,我们将上一个程序的第21到28行替换为如下代码:
1 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 2 dispatch_async(concurrentQueue, taskFirst); 3 NSLog(@"taskfirst 已经加入队列\r\n"); 4 dispatch_async(concurrentQueue, taskSecond); 5 NSLog(@"tasksecond 已经加入队列\r\n");
运行,结果与结果2相同。说明了,taskFirst和taskSecond是同时运行的。
主调度队列(main dispatch queue)
主调度队列中的任务运行在应用程序主线程上,所以,如果你要修改应用程序的界面,他是唯一的选择。演示代码如下:
dispatch_async(dispatch_get_main_queue(),
^{
.....//跟新界面的操作
});
相关文章推荐
- 详解IOS中GCD的使用
- 详解iOS中多线程app开发的GCD队列的使用
- gcd
- OC多线程
- 多线程应该知道的那几件事 GCD NSThread NSOperation
- 多线程编程4 - GCD
- 多线程学习资源
- block && Grand Central Dispatch
- GCD使用指南
- 关于GCD执行任务的理解
- iOS GCD编程
- IOS之多线程
- 2分钟学会GCD
- dispatch_group、dispatch_barrier、基于线程安全的多读单写
- Problem 1612 Hero's gcd
- 欧几里得算法的证明
- 使用GCD
- GCD学习 dispatch_barrier_async
- hdu1452因子和的积性函数
- hdu1852