信号量
dispatch_semaphore_create:创建一个Semaphore并设置信号的总量;
dispatch_semaphore_signal:发送信号,让信号+1;
dispatch_semaphore_wait:可以使总信号量-1,信号总量小于0时就会等待,阻塞所在线程;
dispatch_semaphore作用:
1)保持线程同步,将异步执行任务转换为同步执行任务
2)保证线程安全,为线程加锁
- (void)gcdSemaphoreSync {
NSInteger ret = [self gcdRet];
NSLog(@"异步获取函数返回值 - %ld", ret);
}
- (NSInteger)gcdRet {
__block NSInteger count = 0;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("com.glt.test", DISPATCH_QUEUE_CONCURRENT);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{//模拟异步网络请求
count = 999;
dispatch_semaphore_signal(semaphore);//+1后为0则继续向下执行
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//-1后小于0开始阻塞等待
return count;
}
//保证线程安全,为线程加锁
- (void)gcdSemaphoreLock {
if (!_semaphore) {
_semaphore = dispatch_semaphore_create(1);
}
dispatch_queue_t queue = dispatch_queue_create("com.glt.test", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
dispatch_semaphore_wait(self->_semaphore, DISPATCH_TIME_FOREVER);//-1后等于0开始向下进行,之后再执行到这里此处会小于0,产生阻塞,会等待解锁后继续向下执行
NSLog(@"线程锁-begain");
sleep(3);
NSLog(@"线程锁-end");
dispatch_semaphore_signal(self->_semaphore);//+1后为0,解锁,则继续执行
});
}
方法调用:
[self gcdSemaphoreSync];
[self gcdSemaphoreLock];
[self gcdSemaphoreLock];
[self gcdSemaphoreLock];
[self gcdSemaphoreSync];
[self gcdSemaphoreLock];
[self gcdSemaphoreLock];
[self gcdSemaphoreLock];
运行结果:
异步获取函数返回值 - 999
线程锁-begain
线程锁-end
线程锁-begain
线程锁-end
线程锁-begain
线程锁-end
异步获取函数返回值 - 999
线程锁-begain
线程锁-end
线程锁-begain
线程锁-end
线程锁-begain
线程锁-end