為什麼dispatch_sync在主執行緒會死鎖

lishuanglong521發表於2018-12-05

1.首先看下面一段程式碼

dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{//taskA

//do something
dispatch_sync(queue, ^{//taskB
    //啥也幹不了
});
複製程式碼

});

dispatch_sync函式用於將一個block(任務)提交到佇列中同步執行,直到block執行完後,這個函式才會返回。queue是一個序列佇列,如果先後加入兩個任務,taskA和taskB, 那麼只有taskA執行完之後taskB才能執行。如果taskB是在taskA中加進佇列的,那麼它們依然遵守先進先出原則,即taskA執行完之後taskB才執行,也就是taskB在等待taskA完成。但是因為dispatch_sync的同步特性,taskB執行不完taskA就不算完成,即taskA在等待taskB的完成,這樣就發生了死鎖。

根據上面那份程式碼,我們就可以理解下面的程式碼為什麼會阻塞主執行緒了。

dispatch_queue_t mainQueue = dispatch_get_main_queue();

dispatch_sync(mainQueue, ^{

NSLog(@"hello");
複製程式碼

});

mainQueue是系統建立的,在執行上面的程式碼之前就已經加進去了很多工 dispatch_queue_t queue = dispatch_queue_create("Main", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

//Task A
複製程式碼

}); ... dispatch_sync(queue, ^{

//Task N
複製程式碼

});

在這N個任務裡有一個任務是這樣的: dispatch_sync(queue, ^{

dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
    NSLog(@"hello");
});
複製程式碼

});

所以,發生死鎖就是必然的了。

相關文章