死鎖一直都是在使用多線程時,,需要注意的一個問題。以前對同步,、異步,,串行、并行只有一個模糊的概念,,想想也是時候整理一下了,。再看看之前的博客,,已經(jīng)很久沒有干貨了【說得好像之前有干貨一樣】,所以,,這篇博客,,我盡最大努力,也借鑒了很多其他博客中的例子,,來講解GCD死鎖問題,。 環(huán)境信息: Mac OS X 10.10.5 Xcode 6.4 iOS 8.4 串行與并行 在使用GCD的時候,我們會把需要處理的任務放到Block中,,然后將任務追加到相應的隊列里面,,這個隊列,叫做Dispatch Queue,。然而,存在于兩種Dispatch Queue,,一種是要等待上一個執(zhí)行完,,再執(zhí)行下一個的Serial Dispatch Queue,這叫做串行隊列,;另一種,,則是不需要上一個執(zhí)行完,就能執(zhí)行下一個的Concurrent Dispatch Queue,,叫做并行隊列,。這兩種,均遵循FIFO原則,。
那么,,并行隊列又是怎么在執(zhí)行呢,? 雖然可以同時多個任務的處理,但是并行隊列的處理量,,還是要根據(jù)當前系統(tǒng)狀態(tài)來,。如果當前系統(tǒng)狀態(tài)最多處理2個任務,那么1,、2會排在前面,,3什么時候操作,就看1或者2誰先完成,然后3接在后面,。 串行和并行就簡單說到這里,,關(guān)于它們的技術(shù)點其實還有很多,可以自行了解,。 同步與異步 串行與并行針對的是隊列,,而同步與異步,針對的則是線程,。最大的區(qū)別在于,,同步線程要阻塞當前線程,必須要等待同步線程中的任務執(zhí)行完,,返回以后,,才能繼續(xù)執(zhí)行下一任務;而異步線程則是不用等待,。 僅憑這幾句話還是很難理解,,所以之后準備了很多案例,可以邊分析邊理解,。 GCD API GCD API很多,,這里僅介紹本文用到的。 1. 系統(tǒng)標準提供的兩個隊列
2. 除此之外,,還可以自己生成隊列
接下來是同步與異步線程的創(chuàng)建:
案例與分析 假設你已經(jīng)基本了解了上面提到的知識,,接下來進入案例講解階段。 案例一:
結(jié)果,,控制臺輸出:
分析:
首先執(zhí)行任務1,,這是肯定沒問題的,只是接下來,,程序遇到了同步線程,,那么它會進入等待,等待任務2執(zhí)行完,,然后執(zhí)行任務3,。但這是隊列,,有任務來,當然會將任務加到隊尾,,然后遵循FIFO原則執(zhí)行任務,。那么,現(xiàn)在任務2就會被加到最后,,任務3排在了任務2前面,,問題來了:
案例二:
結(jié)果,,控制臺輸出:
分析: 首先執(zhí)行任務1,,接下來會遇到一個同步線程,程序會進入等待,。等待任務2執(zhí)行完成以后,才能繼續(xù)執(zhí)行任務3,。從dispatch_get_global_queue可以看出,,任務2被加入到了全局的并行隊列中,當并行隊列執(zhí)行完任務2以后,,返回到主隊列,,繼續(xù)執(zhí)行任務3。 案例三:
結(jié)果,,控制臺輸出:
分析: 這個案例沒有使用系統(tǒng)提供的串行或并行隊列,,而是自己通過dispatch_queue_create函數(shù)創(chuàng)建了一個DISPATCH_QUEUE_SERIAL的串行隊列。
案例四:
結(jié)果,控制臺輸出:
分析: 首先,,將【任務1,、異步線程、任務5】加入Main Queue中,,異步線程中的任務是:【任務2,、同步線程、任務4】,。 所以,,先執(zhí)行任務1,然后將異步線程中的任務加入到Global Queue中,,因為異步線程,,所以任務5不用等待,結(jié)果就是2和5的輸出順序不一定,。 然后再看異步線程中的任務執(zhí)行順序,。任務2執(zhí)行完以后,遇到同步線程,。將同步線程中的任務加入到Main Queue中,,這時加入的任務3在任務5的后面。 當任務3執(zhí)行完以后,,沒有了阻塞,,程序繼續(xù)執(zhí)行任務4。 從以上的分析來看,,得到的幾個結(jié)果:1最先執(zhí)行,;2和5順序不一定;4一定在3后面,。 案例五:
結(jié)果,,控制臺輸出:
分析: 和上面幾個案例的分析類似,先來看看都有哪些任務加入了Main Queue:【異步線程,、任務4,、死循環(huán),、任務5】。 在加入到Global Queue異步線程中的任務有:【任務1,、同步線程,、任務3】。 第一個就是異步線程,,任務4不用等待,,所以結(jié)果任務1和任務4順序不一定。 任務4完成后,,程序進入死循環(huán),,Main Queue阻塞。但是加入到Global Queue的異步線程不受影響,,繼續(xù)執(zhí)行任務1后面的同步線程,。 同步線程中,將任務2加入到了主線程,,并且,,任務3等待任務2完成以后才能執(zhí)行。這時的主線程,,已經(jīng)被死循環(huán)阻塞了,。所以任務2無法執(zhí)行,當然任務3也無法執(zhí)行,,在死循環(huán)后的任務5也不會執(zhí)行,。 最終,只能得到1和4順序不定的結(jié)果,。 參考 |
|