GCD死鎖問題

  1. 同步主隊(duì)列執(zhí)行任務(wù)。
    主線程有一個(gè)特點(diǎn):主線程會先執(zhí)行主線程上的代碼片段,然后才會去執(zhí)行放在主隊(duì)列中的任務(wù)。
    同步執(zhí)行 dispatch_sync函數(shù)的特點(diǎn):該函數(shù)只有在該函數(shù)中被添加到某隊(duì)列的某方法執(zhí)行完畢之后才會返回。即 方法會等待 task 執(zhí)行完再返回
    dispatch_sync 函數(shù)本身是放在主線程中執(zhí)行的,也就是說他本身也是屬于主線程執(zhí)行任務(wù)的一部分。根據(jù)主線程的特點(diǎn):主線程會等主線程上的代碼執(zhí)行完畢之后才會去執(zhí)行放置到主隊(duì)列中的 task;再根據(jù) disptach_sync 函數(shù)特點(diǎn), task 不執(zhí)行完畢,dispatch_sync 函數(shù)不返回。這樣,dispatch_sync 為了返回會等 task 執(zhí)行完畢也就是主線程執(zhí)行完,而 task 執(zhí)行又等著主線程上的代碼執(zhí)行完,也即主線程上 dispatch_sync 代碼執(zhí)行完。
  • 主隊(duì)列和主線程相互等待會造成死鎖

    dispatch_sync(dispatch_get_main_queue(), ^(void){
    NSLog(@"這里死鎖了");
    });
    NSLog(@"下面的不執(zhí)行了");
    解決方案:
    dispatch_async(dispatch_get_main_queue(), ^(void){
    NSLog(@"這里死鎖了"); // 現(xiàn)在沒有死鎖
    });
    dispatch_sync(dispatch_get_global_queue(0, 0), ^(void){
    NSLog(@"這里死鎖了"); // 現(xiàn)在沒有死鎖
    });

  1. 異步中包含同步,并且用的都是串行隊(duì)列
    異步串行隊(duì)列中遇到同步串行。同步執(zhí)行阻塞線程,需要等待block 執(zhí)行完往下執(zhí)行,下面又先添加到串行隊(duì)列,需要執(zhí)行完才能執(zhí)行同步任務(wù)。解決方案, 1. 異步和同步使用不同的隊(duì)列。2. 全部使用并行隊(duì)列。
    dispatch_queue_t queue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);

NSLog(@"1");//任務(wù)1

dispatch_async(queue,^{

NSLog(@"2");//任務(wù)2

dispatch_sync(queue,^{

    NSLog(@"3");//任務(wù)3
});

NSLog(@"4");//任務(wù)4

});
NSLog(@"5");//任務(wù)5

// 1
// 5
// 2

解決方案:
dispatch_queue_t queue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);

NSLog(@"1");//任務(wù)1

dispatch_async(queue,^{

NSLog(@"2");//任務(wù)2

dispatch_sync(dispatch_get_main_queue(),^{

    NSLog(@"3");//任務(wù)3
});

NSLog(@"4");//任務(wù)4

});
NSLog(@"5");//任務(wù)5

// 1
// 5
// 2
// 3
// 4

dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_CONCURRENT);

NSLog(@"1");//任務(wù)1

dispatch_async(queue,^{

NSLog(@"2");//任務(wù)2

dispatch_sync(queue,^{

    NSLog(@"3");//任務(wù)3
});

NSLog(@"4");//任務(wù)4

});
NSLog(@"5");//任務(wù)5

// 1
// 5
// 2
// 3
// 4

  1. 阻塞主隊(duì)列,同步主隊(duì)列任務(wù)死鎖。
    dispatch_async(dispatch_get_global_queue(0,0),^{

    NSLog(@"1");//任務(wù)1

    dispatch_sync(dispatch_get_main_queue(),^{

     NSLog(@"2");//任務(wù)2
    

    });
    NSLog(@"3");//任務(wù)3
    });

NSLog(@"4");//任務(wù)4

while(1){

}
NSLog(@"5");//任務(wù)5

// 4
// 1

總結(jié):
造成死鎖的原因是:
在同一個(gè)串行的隊(duì)列中,同步添加block。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容