标签:
GCD——Grand Central Dispatch 是基于C语言的框架,可以充分利用多核,也是苹果官方推荐使用的多线程技术。
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @end 6 7 @implementation ViewController 8 9 /* 10 //写之前,再来温习温习。 11 GCD的使用: 12 一 :队列 13 1.串行队列:添加到队列中的任务是一个一个执行的 14 2.并发(行)队列:添加到队列中的任务是多个同时执行的 15 3.主队列:里面的任务都是在主线程执行的。 16 4.全局队列:并行(发)队列 17 18 二:同步、异步 19 1、同步:需要后面的任务等待,不会开启新的线程,会直接使用当前的线程 20 21 2、异步:不需要后面的任务等待,会开启新的线程 22 */ 23 24 - (void)viewDidLoad { 25 [super viewDidLoad]; 26 27 /*---------创建并发队列---------*/ 28 29 //1.创建并行队列 30 dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT); 31 32 //2.获取全局队列(并行队列) 33 /*优先级<#long identifier#> 34 DISPATCH_QUEUE_PRIORITY_HIGH 35 DISPATCH_QUEUE_PRIORITY_DEFAULT 36 DISPATCH_QUEUE_PRIORITY_LOW 37 DISPATCH_QUEUE_PRIORITY_BACKGROUND 38 */ 39 40 dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 41 42 //(1)在并发队列添加异步任务 43 44 dispatch_async(queue2, ^{ 45 46 for (int i = 0; i < 50 ;i ++) { 47 48 NSLog(@"1---------1"); 49 } 50 51 52 }); 53 54 dispatch_async(queue2, ^{ 55 56 57 for (int i = 0; i < 50 ;i ++) { 58 59 NSLog(@"2---------2"); 60 } 61 62 63 });
打印结果:
1 dispatch_sync(queue2, ^{ 2 3 @autoreleasepool { 4 for (int i = 0; i < 50 ;i ++) { 5 6 NSLog(@"1---------1"); 7 } 8 } 9 }); 10 11 12 dispatch_sync(queue2, ^{ 13 14 @autoreleasepool { 15 for (int i = 0; i < 50 ;i ++) { 16 17 NSLog(@"2---------2"); 18 } 19 } 20 });
这个打印结果相信不用说,我们都知道肯定是先执行1 在执行2
1 /*---------创建串行----------*/ 2 3 dispatch_queue_t queue = dispatch_queue_create("queue3", DISPATCH_QUEUE_SERIAL); 4 5 //向串行队列异步添加任务 6 dispatch_async(queue, ^{ 7 8 for (int i=0; i<50; i++) { 9 NSLog(@"??....i:%d",i); 10 } 11 12 }); 13 14 dispatch_async(queue, ^{ 15 16 for (int i=0; i<50; i++) { 17 NSLog(@"??....i:%d",i); 18 } 19 20 });
打印结果:
尽管是异步添加任务,但是该队列是串行队列,所以猪 先被执行,然后才执行狗。
如果此时我们再在viewDidLoad中也就是在狗的for训话下面添加一个for循环的话你能想象出结果吗?
1 for (int i=0; i<100; i++) { 2 NSLog(@"??....i:%d",i); 3 }
打印结果:
向串行队列同步添加任务
dispatch_sync(queue, ^{ for (int i=0; i<50; i++) { NSLog(@"??....i:%d",i); } }); dispatch_sync(queue, ^{ for (int i=0; i<100; i++) { NSLog(@"??....i:%d",i); } }); for (int i=0; i<100; i++) { NSLog(@"??....i:%d",i); }
运行结果毫无疑问。狗-----》猫----------》猪;时刻记着同步添加任务,不会开启新的线程,会直接使用当前线程。那么肯定这三个任务也是在当前的主线程。
介绍完这些,还有一个重要的东西那就是死锁
让我们来看一下
获取主队列:
dispatch_queue_t mainQueue = dispatch_get_main_queue();
分配任务:
1 NSLog(@"任务开始啦!!!"); 2 //同步添加任务 3 dispatch_sync(mainQueue, ^{ 4 5 NSLog(@"任务添加"); 6 7 }); 8 9 NSLog(@"结束");
毫无疑问第一个打印肯定是 第一行的“任务开始啦!!!”,那么接下来走第三行代码,因为是Block所以第五行的代码要在第九行的打印执行结束后才能被执行(block回调),又因为是同步添加任务,所以第九行代码要在上面的任务执行完才能开始。所以编译器犹豫不知道该执行那一个。会造成死锁。
打印结果:
总结:(1)在使用主队列时,绝对不可以在主队列中同步添加任务,会造成死锁。
(2)并发队列:同步添加不会开启新的线程,异步添加会开启多条线程。
(3)串行队列:同步添加不会开启新的线程,异步添加会开启一条线程。
(4)由(2)和(3)得出结论同步添加任务,不具备开启线程的能力。异步添加任务开启线程的条数由当前队列决定,串行队列开启一条线程,并行队列开启多条。
标签:
原文地址:http://www.cnblogs.com/wzh521/p/4823488.html