GCD的使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCD的使用相关的知识,希望对你有一定的参考价值。
Grand Central Dispatch :牛逼的中枢调度器。
1.优势
最大的优势就是自动,自动利用更多的CPU,自动管理线程的生命周期,不需要任何线程管理代码。
将需要执行的任务添加到队列中,GCD会自动将队列中的人物取出,放到对应的线程中去执行。
遵循原则:FIFO原则:先进先出,后进后出(栈)
2.基本概念
队列:用来存放任务;
并发队列:可以多个任务同时执行(即自动开启多个线程),并发功能只能在异步(dispatch_async)函数下使用
串行队列:任务一个接一个的执行
任务:执行的操作;
同步:在当前的线程中执行任务,不具备开启新线程的能力;
异步:在新的线程中执行任务,具备开启新线程的能力;
并发:多个任务同时执行;
串行:只有当前的任务执行完毕后,才能执行下一个任务。
3.任务执行
同步执行:dispatch_sync(参数一:队列 , 参数二:任务);其中任务是一个block
异步执行:dispatch_async(参数一:队列 , 参数二:任务);其中任务是一个block
本质区别:同步在当前的线程中执行,异步是开辟另一条线程去执行任务。
执行步骤:
(1)定制队列、(2)提交任务
4.代码
主队列(串行队列)和全局队列(并发队列):
1 -(void)mainAndGlobal{ 2 3 4 // 获取主队列,串行队列 5 dispatch_queue_t main_queue = dispatch_get_main_queue(); 6 7 // 获取全局队列,并发队列 8 dispatch_queue_t global_queue = dispatch_get_global_queue(0, 0); 9 10 /*dispatch_get_global_queue(long identifier, 0) 11 参数一:全局队列的优先级 12 #define DISPATCH_QUEUE_PRIORITY_HIGH 2 13 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 14 #define DISPATCH_QUEUE_PRIORITY_LOW (-2) 15 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 16 参数二:并没有什么~用 17 */ 18 19 //1.向全局队列中提交异步任务(开辟子线程去执行任务) 20 dispatch_async(global_queue, ^{ 21 22 NSLog(@"1.向并发队列中提交异步任务--%@",[NSThread currentThread]); 23 }); 24 dispatch_async(global_queue, ^{ 25 26 NSLog(@"2.向并发队列中提交异步任务--%@",[NSThread currentThread]); 27 }); 28 29 //2.向主队列中提交异步任务(在当前的线程中执行任务,且任务发生在当前线程的所有任务执行完毕后) 30 dispatch_async(main_queue, ^{ 31 32 NSLog(@"1.向串行队列中提交异步任务--%@",[NSThread currentThread]); 33 }); 34 dispatch_async(main_queue, ^{ 35 36 NSLog(@"2.向串行队列中提交异步任务--%@",[NSThread currentThread]); 37 }); 38 39 //3.向全局队列中提交同步任务(任务发生在当前线程) 40 dispatch_sync(global_queue, ^{ 41 42 NSLog(@"1.向并发队列中提交同步任务--%@",[NSThread currentThread]); 43 }); 44 dispatch_sync(global_queue, ^{ 45 46 NSLog(@"2.向并发队列中提交同步任务--%@",[NSThread currentThread]); 47 }); 48 49 // 4.向主队列中提交同步任务(造成线程的死锁,需要避免的情况) 50 dispatch_sync(main_queue, ^{ 51 52 NSLog(@"1.向串行队列中提交同步任务--%@",[NSThread currentThread]); 53 }); 54 dispatch_sync(main_queue, ^{ 55 56 NSLog(@"2.向串行队列中提交同步任务--%@",[NSThread currentThread]); 57 }); 58 59 /* 60 66 }
总结:
1.只要是同步任务,任务都是在当前的线程中执行,不开辟子线程,所以会阻塞当前线程只有当前任务完成后才能去执行下一个任务,所以要避免死循环。 2.异步任务在全局队列中才能开辟子线程,在主线程中不开辟子线程 3.同步任务不能添加到主队列中,会造成线程死锁。
创建队列:
1 /* 2 dispatch_queue_create(const char *label, dispatch_queue_attr_t attr) 3 参数一:char型指针 4 参数二:指定队列的类型 5 DISPATCH_QUEUE_SERIAL:串行 6 DISPATCH_QUEUE_CONCURRENT:并发 7 */ 8 9 dispatch_queue_t serial_q = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL); 10 11 dispatch_queue_t concurrent_q = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
提交任务代码同上,需要注意的是:
1 //向串行队列中提交同步任务(会造成死锁) 2 dispatch_sync(serial_q, ^{ 3 4 NSLog(@"3.向串行队列中提交同步任务--%@",[NSThread currentThread]); 5 6 dispatch_sync(serial_q, ^{ 7 8 NSLog(@"4.向串行队列中提交同步任务--%@",[NSThread currentThread]); 9 }); 10 11 }); 12 13 //此种情况不会造成死锁 14 dispatch_sync(serial_q, ^{ 15 16 NSLog(@"3.向串行队列中提交同步任务--%@",[NSThread currentThread]); 17 }); 18 19 dispatch_sync(serial_q, ^{ 20 21 NSLog(@"4.向串行队列中提交同步任务--%@",[NSThread currentThread]); 22 });
总结:在一个串行队列执行的代码中,如果向此队列同步提交一个任务,会造成死锁。这就要求要避免在串行队列中同步提交任务给本身的队列。
以上是关于GCD的使用的主要内容,如果未能解决你的问题,请参考以下文章