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;
}
};