GCD死锁的几种情况
...................死锁的第一种情况:....................
NSLog(@"=================4");
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"=================5");
});
NSLog(@"=================6");
以上代码都是在主线程中,主队列是串行队列。
1.同步添加任务(
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"=================5");
});
)的时候,需要主队列中任务都执行完毕,所以需要NSLog(@"=================6”);也要执行完毕。
2.又因为主队列是串行队列,代码NSLog(@"=================6”);需要在它的上一步
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"=================5");
});执行完毕才能执行。
3.相互等待,造成死锁。
...................死锁的第二种情况:....................
全局队列global_queue是一个并行队列。
1.给全局队列global_queue添加一个任务(异步添加)
任务分为三部分:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"=================1%@",[NSThread currentThread]);//第一部分
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"=================2%@",[NSThread currentThread]);
});//第二部分 该部分给main_queue同步添加了一个任务,该任务添加到主队列的前提是主队列的任务全部执行完毕(如果主队列被堵塞了,就要一直等着)
NSLog(@"=================3%@",[NSThread currentThread]);//第三部分
});
2.
NSLog(@"==========4.%@",[NSThread currentThread]);
3.
while (1) {
}//主线程阻塞
4.
NSLog(@"========2==阻塞主线程%@",[NSThread currentThread]);
.................死锁的第三种情况:....................
//串行队列 SERIAL
dispatch_queue_t q_1 = dispatch_queue_create("queue_1", DISPATCH_QUEUE_SERIAL); //自定义的串行队列
1.给串行队列q_1添加任务:(异步添加)任务分为三部分
dispatch_async(q_1, ^{
//第一部分
NSLog(@"q_1异步提交");
NSLog(@"q_1异步提交");
//第二部分 在异步提交中放一个同步提交
dispatch_sync(q_1, ^{
//走不进来
//走不进来
NSLog(@"在异步提交中放的一个同步提交");
});//同步提交该任务,需要队列q_1中的所有任务都执行完,才能执行该任务,所以需要第三部分(NSLog(@"????????????");)也执行完毕。又因为q_1是串行队列,要想走到第三部分,需要先走完第二部分。相互等待,造成死锁。
//第三部分
NSLog(@"????????????");
});
2.
NSLog(@"over over over over over over ");
3.给串行队列q_1添加任务:(异步添加)
dispatch_async(q_1, ^{
NSLog(@"2222222222");
NSLog(@"2222222222");
});//这一步是异步添加到队列q_1,虽然添加到了队列q_1上,但是因为串行队列卡死在该任务的上一步,所以这一步也不会执行。
死锁原因总结:
往队列中同步添加任务:队列里的任务都执行完才能执行那个刚提交的那个同步任务。
附:串行队列
//串行队列 SERIAL
dispatch_queue_t q_1 = dispatch_queue_create("queue_1", DISPATCH_QUEUE_SERIAL);
//异步提交
任务1:
dispatch_async(q_1, ^{
NSLog(@"111111111111");
});
NSLog(@"111111111111");
});
任务2:
dispatch_async(q_1, ^{
NSLog(@"2222222222");
NSLog(@"2222222222");
while (1) {
}//卡在了这里
});
任务3:
dispatch_async(q_1, ^{
NSLog(@"333333333");
NSLog(@"333333333");
});//因为是串行队列,队列卡在了任务2,所以虽然任务3已经被提交到了队列中,也走不到任务3里面。