GCD的幾個重要概念:任務(wù)、隊(duì)列、隊(duì)列組、信號量
dispatch_group用來管理dispatch_queue_t,dispatch_queue_t用來管理task。
dispatch_group可以監(jiān)聽到所有被管理的dispatch_queue_t執(zhí)行結(jié)束
常用方法:
/**
創(chuàng)建dispatch_group_t
*/
dispatch_group_t group = dispatch_group_create();
/**
將任務(wù)tast添加到queue,并被group管理
@param group 隊(duì)列組
@param queue 隊(duì)列
@param tast 任務(wù)
*/
dispatch_group_async(group, queue1, tast);
/**
阻塞當(dāng)前線程
@param timeout 阻塞最大時長
*/
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
/**
監(jiān)聽group的完成狀態(tài),全部完成觸發(fā)回調(diào)
@param dispatch_get_main_queue 回調(diào)執(zhí)行的線程
*/
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"main,%@",[NSThread currentThread]);
});
dispatch_group_enter 標(biāo)志著一個任務(wù)追加到 group,執(zhí)行一次,相當(dāng)于 group 中未執(zhí)行完畢任務(wù)數(shù)+1
dispatch_group_leave 標(biāo)志著一個任務(wù)離開了 group,執(zhí)行一次,相當(dāng)于 group 中未執(zhí)行完畢任務(wù)數(shù)-1。
當(dāng) group 中未執(zhí)行完畢任務(wù)數(shù)為0的時候,才會使dispatch_group_wait解除阻塞,以及執(zhí)行追加到dispatch_group_notify中的任務(wù)。
dispatch_group_enter(group);
dispatch_group_leave(group);
信號量dispatch_semaphore
信號量是基于計數(shù)器的一種多線程同步機(jī)制,用來管理對資源的并發(fā)訪問。
dispatch_group經(jīng)常會與dispatch_semaphore一起使用,主要作用如下:
- 保持線程同步,將異步執(zhí)行任務(wù)轉(zhuǎn)換為同步執(zhí)行任務(wù)
- 保證線程安全,為線程加鎖
主要方法如下:
dispatch_semaphore_create:創(chuàng)建一個Semaphore并初始化信號的總量
dispatch_semaphore_signal:發(fā)送一個信號,讓信號總量加1
dispatch_semaphore_wait:可以使總信號量減1,當(dāng)信號總量為0時就會一直等待(阻塞所在線程),否則就可以正常執(zhí)行。
線程鎖 NSLock
線程鎖有一種很有趣的玩法,利用C++特性,在聲明C++類臨時變量時,會自動執(zhí)行構(gòu)造函數(shù),離開作用域會執(zhí)行析構(gòu)函數(shù);
因?yàn)?,可以在一個作用域內(nèi),聲明C++類。構(gòu)造函數(shù)執(zhí)行l(wèi)ock方法,析構(gòu)函數(shù)執(zhí)行unlock方法。即可完成該作用域的線程鎖。
class CScopedLock {
NSRecursiveLock *m_oLock;
public:
CScopedLock(NSRecursiveLock *oLock) : m_oLock(oLock) {
[m_oLock lock];
}
~CScopedLock() {
[m_oLock unlock];
m_oLock = nil;
}
};