dispatch_group詳解
GCD的幾個重要概念:任務、佇列、佇列組、訊號量
dispatch_group用來管理dispatch_queue_t,dispatch_queue_t用來管理task。
dispatch_group可以監聽到所有被管理的dispatch_queue_t執行結束
常用方法:
/** 建立dispatch_group_t */ dispatch_group_t group = dispatch_group_create(); /** 將任務tast新增到queue,並被group管理 @param group 佇列組 @param queue 佇列 @param tast任務 */ dispatch_group_async(group, queue1, tast); /** 阻塞當前執行緒 @param timeout 阻塞最大時長 */ dispatch_group_wait(group, DISPATCH_TIME_FOREVER) /** 監聽group的完成狀態,全部完成觸發回撥 @param dispatch_get_main_queue 回撥執行的執行緒 */ dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"main,%@",[NSThread currentThread]); });
dispatch_group_enter 標誌著一個任務追加到 group,執行一次,相當於 group 中未執行完畢任務數+1
dispatch_group_leave 標誌著一個任務離開了 group,執行一次,相當於 group 中未執行完畢任務數-1。
當 group 中未執行完畢任務數為0的時候,才會使dispatch_group_wait解除阻塞,以及執行追加到dispatch_group_notify中的任務。
dispatch_group_enter(group); dispatch_group_leave(group);
訊號量dispatch_semaphore
訊號量是基於計數器的一種多執行緒同步機制,用來管理對資源的併發訪問。
dispatch_group經常會與dispatch_semaphore一起使用,主要作用如下:
- 保持執行緒同步,將非同步執行任務轉換為同步執行任務
- 保證執行緒安全,為執行緒加鎖
主要方法如下:
dispatch_semaphore_create:建立一個Semaphore並初始化訊號的總量 dispatch_semaphore_signal:傳送一個訊號,讓訊號總量加1 dispatch_semaphore_wait:可以使總訊號量減1,當訊號總量為0時就會一直等待(阻塞所線上程),否則就可以正常執行。
執行緒鎖 NSLock
執行緒鎖有一種很有趣的玩法,利用C++特性,在宣告C++類臨時變數時,會自動執行建構函式,離開作用域會執行解構函式;
因為,可以在一個作用域內,宣告C++類。建構函式執行lock方法,解構函式執行unlock方法。即可完成該作用域的執行緒鎖。
class CScopedLock { NSRecursiveLock *m_oLock; public: CScopedLock(NSRecursiveLock *oLock) : m_oLock(oLock) { [m_oLock lock]; } ~CScopedLock() { [m_oLock unlock]; m_oLock = nil; } };