dispatch_sync到底為什么死鎖

之前看面試題知道下面代碼會死鎖,網(wǎng)上說是因為相互等待,等等,總覺得難以理解

dispatch_sync(dispatch_get_main_queue(), ^{

NSLog(@"死鎖了");

});

經(jīng)過一下午的仔細研究,算是有點收獲,下面分享給大家,不對的地方歡迎指正


一:首先介紹下基本概念

隊列:用于存放任務(wù)。一共有兩種隊列,串行隊列并行隊列

同步(sync)和異步(async)的主要區(qū)別在于會不會阻塞當前線程,直到Block中的任務(wù)執(zhí)行完畢!

如果是同步(sync)操作,它會阻塞當前線程并等待Block中的任務(wù)執(zhí)行完畢,然后當前線程才會繼續(xù)往下運行。

如果是異步(async)操作,當前線程會直接往下執(zhí)行,它不會阻塞當前線程


二:死鎖

官方文檔指出:dispatch_sync的當前執(zhí)行隊列與提交block執(zhí)行的目標隊列相同時將造成死鎖。

Submits a block to a dispatch queue for synchronous execution. Unlike dispatch_async, this function does not return until the block has finished. Calling this function and targeting the current queue results in deadlock.

dispatch_sync(dispatch_get_main_queue(), ^{

NSLog(@"死鎖了");

});


根據(jù)文檔所說,此任務(wù)本身(整個代碼)在主隊列中,而要添加的任務(wù)(NSLog(@"死鎖了");)也要添加到主隊列,它會死鎖。這是為什么呢?

假設(shè)自己為A任務(wù),A任務(wù)所在的隊列為主隊列,A任務(wù)正在執(zhí)行,A任務(wù)的代碼是添加B任務(wù)到主隊列并使B任務(wù)執(zhí)行完畢,然后B任務(wù)就被添加到主隊列,可是它要等待A任務(wù)執(zhí)行完,才輪到它執(zhí)行,A任務(wù)等待B任務(wù),B任務(wù)又等待A任務(wù),因此形成死鎖。

為了驗證觀點,我試了下面的代碼:

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

dispatch_sync(queue, ^{

? ? ? ?NSLog(@"正常打印");

? ? ? dispatch_sync(queue, ^{

? ? ? ? ? ? ? ? ?NSLog(@"死鎖了");

? ? ? ? ? ? ? ? });

? ? ?});

NSLog(@"死鎖了");

因為是同步往“queue”添加任務(wù),可是本身又是在“queue”中執(zhí)行,再次循環(huán)等待,死鎖發(fā)生。

參考自鏈接:

https://www.zhihu.com/question/23338200/answer/57844956

http://www.itdecent.cn/p/0b0d9b1f1f19

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

相關(guān)閱讀更多精彩內(nèi)容

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