GCD 的一點疑惑與自解

GCD 其實已經(jīng)了解了很久了,在實際工程中也會經(jīng)常用,但是其實很多實踐都是淺嘗輒止。

最近又在回頭看這塊兒的內(nèi)容,有一些知識點,原來不甚明白的,現(xiàn)在有了新的認識,剛好也記錄下。

GCD 是一套方案,GCD 本身管理了一組線程池,GCD 負責線程池中的線程創(chuàng)建銷毀、并且這種能力是動態(tài)化的,即可以充分利用當前 CPU 的多核特性。
添加到 GCD 隊列中的任務,會由 GCD 來決定運行在哪一個線程上。也就是說,GCD Queue 是一個抽象概念, task 是添加到 Queue 中不假,但是實際仍然是運行在線程上的。

GCD Concurrent Queue 并行隊列

GCD 的隊列中的 task 遵循 FIFO (First In First Out)原則,但是 task 完成的順序是不可測的。

上面的這段描述,是在當時閱讀官方文檔的時候,產(chǎn)生了疑惑,我的想法是,既然 task 是按照先后添加到 Queue 中的順序進行執(zhí)行的,那為啥完成時間就不一定了呢?

現(xiàn)在明白了,task 的執(zhí)行壓根和 Queue 關系不大,GCD 只是按照添加順序從 Queue 中一個個拿出 task,扔到線程上去執(zhí)行。有的 task 一會就完成了,有的需要比較長的時間,當然這個完成順序就不一定了。

現(xiàn)在想想,當時應該是想當然的認為 GCD 只有在完成上一個任務后才會開啟下一個任務,跟串行隊列混淆了,從而導致疑惑的。

GCD 串行隊列

串行隊列就是只有完成上一個 task ,才會進行下一個 task 的執(zhí)行。
所以完成順序與添加順序是相同的。

Objc GCD 隊列疑惑

gcd-queues.png

上圖是摘錄自 Objc.cn 中關于 GCD 隊列的一張圖。
但是在閱讀時,我有下面幾點疑惑:

  • 為什么 Custom Queues 這一層的關系如此復雜。
  • 為什么 Serial Queue 既指向了 Serial Queue ,又能指向 Concurrent Queue。
  • 最上面一層中的 Serial Queue 和 倒數(shù)第二層中的 Queues 有什么關系。

GCD 公開有 5 個不同的隊列:運行在主線程中的 main queue,3 個不同優(yōu)先級的后臺隊列,以及一個優(yōu)先級更低的后臺隊列(用于 I/O)。 另外,開發(fā)者可以創(chuàng)建自定義隊列:串行或者并行隊列。自定義隊列非常強大,在自定義隊列中被調度的所有 block 最終都將被放入到系統(tǒng)的全局隊列中和線程池中。

Objc 原文如上描述。

細細品味,其意思是,GCD Queues 有 5 大欽定的 Queue。
開發(fā)者當然也可以自定義 Queue(使用 dispatch_queue_create 函數(shù)), 前面說過,Queue 是一個抽象概念,只是簡單的保存 task 而已,最終 task 還是要在 GCD Thread Pool 中完成的。

目標隊列 Target Queue

之前講過,task 最終是要從 Queue 中放到線程池中執(zhí)行的。
其實還有一種情況,就是 task 可以從一個 Queue 中放到另一個 Queue 中。
需要設置當前 Queue 的 TargetQueue。
了解了這個概念,就能很清楚的明白上面的圖了。

為了更加清楚的闡述這張圖的表達意圖,可以從這幾條線說起:

S1 -> Main Queue

MainQueue 這個隊列中的 task 最終都會放到主線程上執(zhí)行。如果所示,MainQueue 是指向 Main Thread。
也就是說,如果自定義隊列時,如果這個自定義串行隊列的 Target Queue 是 Main Queue,那么這些 task 將都會放在主線程執(zhí)行。

S3 -> Default Priority Queue

這里的意思很簡單,自定義隊列的默認 Target Queue 就是 Default Priority Queue,這也就是 Objc 所解釋的 在自定義隊列中被調度的所有 block 最終都將被放入到系統(tǒng)的全局隊列中和線程池中 。
在 S3 隊列中的任務,會一個接著一個地放入到 Global Queue 中,然后被執(zhí)行。在前一個 task 完成之后,才會繼續(xù)下一個 task。

C2 -> Default Priority Queue

同上,不過這里,會一咕嚕的將 C2 中的 task 往 Global Queue 中放,不用管上一個 task 是否完成。

S2 -> S3

Serial Queue 的 target queue 同樣是 Serial Queue

C1 + S4 -> C2

C1 的 Concurrent Queue 的 target queue = Concurrent Queue
這個就比較高級了。
在這個模式下,S4 中的 task 串行,C1 中的 task 并行。
但是最終它們這些任務都放在一個并發(fā)隊列中。

最后

以上是個人對于 GCD 的一些見解,如有描述不對,還請及時指正。

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

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

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