GCD的2个核心概念
- 任务:执行什么操作
- 队列:用来存放任务
GCD会自动将队列中的任务取出,放到对应的线程中执行;
任务的取出遵循对象的FIFO原则:先进先出,后进后出
程序员要做的,将任务添加到队列;队列按照程序员指定的方式,调度任务。执行任务的方法:同步/异步
同步:一个任务没有结束,就不会执行下一个任务
异步:不用等待任务执行完毕,就会执行下一个任务
主队列(dispatch_get_main_queue()):供主线程调度,是串行队列
全局队列(dispatch_get_global_queue(0, 0)):是并行队列
现在有以下几种组合:
串行异步
串行同步
并行同步
并行异步
先看下四种情况是否开辟新线程,我写了代码执行得到如下log
serial async thread is <NSThread: 0x1006008f0>{number = 2, name = (null)}
serial sync thread is <NSThread: 0x10050d920>{number = 1, name = main}
concurrent sync thread is <NSThread: 0x10050d920>{number = 1, name = main}
concurrent async thread is <NSThread: 0x1006008f0>{number = 2, name = (null)}
global queue async thread is <NSThread: 0x1006008f0>{number = 2, name = (null)}
global queue sync thread is <NSThread: 0x10050d920>{number = 1, name = main}
可以看到
串行异步 开辟新线程
串行同步 不开辟新线程
并行同步 不开辟新线程
并行异步 开辟新线程
总结:线程的开辟跟队列是否是串行还是并行无关,异步开辟新线程,同步不开辟新线程
看log中没有主队列的log,因为主队列异步没执行,主队列同步会造成crash。
主队列同步执行为什么会Crash?
首先我们先看下串行队列同步是否有问题,代码如下:
NSLog(@"串行同步 start");
dispatch_queue_t serialSync = dispatch_queue_create("Judith_SerialSQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialSync, ^{
NSLog(@"serial sync thread is %@",[NSThread currentThread]);
});
NSLog(@"串行同步 end");
得到的log如下:
串行同步 start
serial sync thread is <NSThread: 0x100605cf0>{number = 1, name = main}
串行同步 end
运行正常,所以串行队列同步是不会crash的,只是主队列同步会crash,那为什么主队列同步会导致crash呢?
我们看下主队列同步的代码:
+ (void)quenTest {
//主队列同步 死锁
NSLog(@"主队列同步 start");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"main queue sync thread is %@",[NSThread currentThread]);
});
NSLog(@"主队列同步 end");
}
主队列在执行dispatch_sync,函数会把一个block加入到指定的队列,此函数要求执行完block才返回,函数要求此时去执行block内容,但是主队列此时还卡在函数,函数线程还在,不能去执行block,也就是说函数和block是两个任务,在队列中前后关系,两个任务相互等待,导致死锁,产生crash。若是异步,函数添加完block就返回,顺序执行block内容,不存在死锁问题。
本文代码地址 GCDTest










网友评论