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异步提交");
       
       //第二部分 在异步提交中放一个同步提交
        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");
       
    });//这一步是异步添加到队列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");
   
   
    });
   
任务2:  
    dispatch_async(q_1, ^{
       
        NSLog(@"2222222222");
        while (1) {   
           
        }//卡在了这里
    });
 
 任务3:
    dispatch_async(q_1, ^{
       
        NSLog(@"333333333");
       
       
    });//因为是串行队列,队列卡在了任务2,所以虽然任务3已经被提交到了队列中,也走不到任务3里面。
 
 
原文地址:https://www.cnblogs.com/zh-li/p/5140610.html