iOS| #28 | GCD 筆記 part3. DispatchSemaphore
在iOS| #28 part2.提到了DispatchGroup的使用,這次會說明另一個相似的物件,叫做DispatchSemaphore。
DispatchSemaphore的功能與DispatchGroup相當類似,但Semaphore可以利用參數value控制資源的運用(例如:同時只能執行2個任務)。
名詞解釋
在正式講解前有一些DispatchSemaphore的method可能要先熟悉一下
- signal
Semaphore計數增加 - wait
Semaphore計數減少
程式範例
官方文件說明主要會有兩種做法:
- 預設value為0,當執行任務時會呼叫wait,使其value -1(變成負數)。這時候執行緒會block住,直到呼叫signal,使其value +1(變回零),這時候才會繼續執行後續的任務。
- 預設value為任一正整數,目的是為了管理同時可以運作的執行緒數量。
以下就讓我們看看範例:
- 首先建立一個project,實作func dispatchSemaphoreTest()。
- 在viewDidLoad()呼叫此func 。
3. 生成DispatchSemaphore、DispatchQueue之後測試方便使用。
接下來會用程式範例在func dispatchSemaphoreTest()中 print出一些東西來觀察利用DispatchSemaphore執行任務時的狀況
- 預設value為0
任務會按照順序完成,與iOS| #28 part2.提到的DispatchGroup使用wait的結果一樣
結果如下:
開門洗手吃飯
- 預設value為5
同時最多只能執行5個任務。依照Semaphore的特性,value為負的話執行緒會被block住,直到value≥0。
這邊的範例稍微多了幾個步驟:
- 宣告屬性count負責記錄現在有幾項任務
2. 實作func countValue()
當做完五項任務時會print出訊息,並將計數器歸零
//控制counterfunc countValue(){ count += 1 if count == 5 { print("已完成五項任務") count = 0 }}
3. 實作func dispatchSemaphoreTest()範例內容
補充:在func dispatchSemaphoreTest()中會使用asyncAfter & sleep(1)是為了讓gif結果看起來更明顯,因為任務非常簡單,要避免程式一下子就做完所有事。
結果如下:
補充:
在使用上會有一些要注意的地方,經過測試後將這些情境列在下方
- 使用呼叫wait()使value為負數的話,會讓程式碼停在wait()這邊,在此以後的其他任務會暫時不會被執行。
透過以下的執行結果可以觀察程式碼34行的print(“完成”)
並沒有馬上被執行。因為使用Semaphore的緣故等到三秒後執行完signal()使value≥0才會繼續執行。
- 若value為負數的話,一直沒有呼叫signal()。執行緒會永遠block住,無法執行任何動作。
系列文章:
若內容有誤煩請指教,感謝收看。