关于GCD的使用方法,网上能找到一大堆,对于死锁这个问题,也是很多,但是反而让感觉很混乱,再次整理一下,希望大神们看到能解答我的疑惑,说的不对的地方,也请指出。
基础概念:
同步:会阻塞当前线程,等block(任务)执行完成后,当前线程才会继续往下执行
异步:不会阻塞当前线程
上代码:
1. dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"死锁");
});
2. dispatch_queue_t test =dispatch_queue_create("test.queue",DISPATCH_QUEUE_SERIAL);
dispatch_sync(test, ^{
NSLog(@"没有死锁");
});
对于第一种情况,dispatch_sync 调用时,会阻塞queue所在的线程(主线程),将block(任务)插入main_queue中执行,main_queue是在主线程执行,但是这个时候主线程已经被dispatch_sync阻塞了,所以导致死锁。
对于第二种情况,创建了一个串行队列,然后同步执行。这里比较不理解,main_queue 和新建的队列一样都是串行队列,也都是在主线程里面运行的。但是这时候并没有发生死锁现象,而是正常的执行了,按照第一种情况的认识,dispatch_sync也应该会阻塞test所在的主线程从而导致死锁。
然而,对照 新创建的串行队列test与main_queue,可以发现还是有区别的,那就是main_queue 已经在线程中了,但是test并没有,所以改一下第二段:
3. dispatch_sync(test, ^{
dispatch_sync(test, ^{
NSLog(@"死锁");
});
});
第三种情况,发现又会产生死锁现象,ps:换成异步调用后在同步,还是会发生死锁现象。原因应该是:第二次同步调用的时候,阻塞了第一次将test所在的线程。导致死锁。
但是对于第二种情况,一直不理解是为什么,如果有大神知道,请回复我。
所能得到的一个结果是:在已经放到线程中执行的queue(串行)中,再同步调用当前queue,往里面插入任务,就会发生死锁现象。