One minute
關於GCD的一些筆記-1
關於GCD
什麼是GCD?GCD的全名為Grand Central Dispatch
基本上就是執行緒管理中心。用比較不嚴謹的敘述來說的話,它就是幫助你處理多執行緒的管理器。 利用GCD,可以很方便地操控各種需要多執行緒的情境
GCD的運作原理
這邊姑且先不討論程式面的東西,先從抽象一點的地方來看。
基本上來說,GCD掌控了Queue,而Queue包含了Work Item,最後WorkItem就是要執行的Closure
Queue
Queue可以被翻成「佇列」,但是看了翻譯還是不知道是什麼意思。
可以想像成是去看電影的時候排隊的人潮,隊伍本身就是Queue。
先排進去的人,就可以先買票。這就是 FIFO ( First In First Out ) 的概念。
Queue裡面放的是WorkItem,用買票的例子來解釋的話,就是你要買哪場的票這件事。
Queue又有分Serial跟Concurrent兩種
Serial:就是一次只執行一個WorkItem,在這個WorkItem還沒執行完之前,不會取下一個來執行。
Concurrent:自然就是相對於Serial,當第一個WorkItem被取出後,並不會等這個WorkItem被執行完,就接著取出下一個WorkItem,一直到這個Queue中所有WorkItem被拿出來執行為止(或是你吃光了所有系統可分配的Thread,也會被暫停)
講完了Queue的類型,再來就是Queue要怎麼執行WorkItem
這部分就分為 Sync(同步)跟Async(非同步) 兩種
Sync:
當前的Queue會被擋住,不能往下執行,等待WorkItem被執行完以後,才會繼續往下執行。在這個時間點中只有一個Queue可以運作。
所以在用sync方法的時候一定要非常小心一個重點
如果當前的執行中的Queue是Serial,而且你又要拿來做sync的動作的話,就會造成Deadlock
舉個例子,下面這段程式如果用Main Queue來執行,就永遠不會執行到print
發生的原因很簡單,因為當系統執行到DispatchQueue.main.sync
這段的時候,系統就知道「阿,要塞住當前的Queue」也就是MainQueue,然後又叫MainQueue去做事。但是這時候Main Queue已經被塞住了,又怎麼能去print呢?
Async:非同步代表的是它不會塞住當前的執行緒 所以當Queue用非同步去執行WorkItem的時候,系統會開一條新的Thread去執行這個WorkItem,然後就繼續往下執行。
非同步程式可以保證當前的Thread執行不會被卡住,因為都會開一個新的Thread去執行WorkItem。但是非同步程式常常會遇到的就是他不會有返回值,所以很容易出現Callback Hell
的狀況。不過這不是本篇要講的重點,後面寫PromiseKit
或RxSwift
的時候再說。
舉幾個例子,這可以直接貼到Playground裡面來執行
結果是比較顯而易見的,就跟程式執行順序一致。
do something before sync
sync
sync
sync
sync
sync
sync
do something after sync
那麼用差不多的架構,只不過把sync換成async的話,會怎麼樣的?
這邊就差很多了。
因為是另外開執行緒去做事,所以跟看到的結果就會有明顯差異
do something before async
do something after async
async
async
async
async
async
async
所以關於怎麼挑選自己要用的Queue,就可以從這四個裡面去兜出來。
具體的挑選就看自己的情境來決定。
本來還要寫一些DispatchGroup、訊號機等筆記的,但是寫的有點煩了。
要改的東西太多了,那麼就改天吧。