三个函数
1.dispatch_semaphore_t
dispatch_semaphore_create(long value); 创建信号量
参数value须大于或等于0
2.long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等位函数
信号量-1,之后
若信号量<0,当前线程被阻塞
若信号量>=0,当前线程继续执行
如果超时返回非0值,否则返回0
3.long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
信号量+1,之后
若信号量>=0, 会唤醒一个正在等待的线程,然后返回
如果有线程被唤醒,返回非0值,否则返回0
类比理解
我喜欢用排队上厕所进行类比,帮助自己理解。
想象一个厕所有三个坑,这个坑位总数就是dispatch_semaphore_create(long value) 函数对应的value
此时三个坑都被人占了,门口又来了一个人,发现没有坑了(信号量为0),只能在门口等着。
对应执行了这个函数dispatch_semaphore_wait,信号量-1后小于0,阻塞当前线程(不能拉也不能撒);
过了一会里面有个人完事儿了,空出一个坑位,他会通知下一个正在等待的人进去。
相当于执行dispatch_semaphore_signal函数,使信号量+1,此时信号量等于0了,唤醒等待的线程,门口的人就可以进去了。
应用举例
1.线程锁
以SDWebImage为例
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
_operationsLock = dispatch_semaphore_create(1); // 信号量初始化为1
LOCK(sself.operationsLock);
[sself.URLOperations removeObjectForKey:url]; // 锁内执行,保证只有一个线程访问
UNLOCK(sself.operationsLock);
2.线程同步
- (void)threadSync {
// 主线程
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block BOOL allDone = NO;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 子线程
allDone = YES;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"all done : %d", allDone);
}
子线程执行完之后才会走log, allDone为1
若把dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);注释掉,allDone为0
网友评论