iOS开发之多线程

信号量dispatch_semaphore的使用注意点

2021-03-11  本文已影响0人  Sweet丶

开发中,我们可以使用信号量dispatch_semaphore来做两个事情:

代码如下:

// 创建信号量为1的信号时,一次只能一个线程执行,可当做锁使用(可参考SDWebImage)
_semaphore = dispatch_semaphore_create(1);
// 调用dispatch_semaphore_wait:如果当前信号量大于0则使信号量-1后执行子线程任务;当前信号量为0则等待信号量
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
// 增加计数信号量。如果前一个值小于零,此函数将唤醒当前在wait中线程
dispatch_semaphore_signal(self.semaphore);
使用注意点:
  1. 主线程中使用dispatch_semaphore_wait时,如果此时的信号量为0,那么就会导致主线程堵塞在这里,等待信号量;如果堵塞在这里时,我们有回调到主线程执行的任务,也会得不到执行。
// 主线程中调用testDispatchSemaphore,测试上面的堵塞情况。
- (void)testDispatchSemaphore{// dispatch_semaphore_create(0);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 来不到这里执行
        NSLog(@"dispatch_semaphore_wait:---0000");
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 子线程消耗信号量后子线程发送信号量
            [NSThread sleepForTimeInterval:2];
            intptr_t value = dispatch_semaphore_signal(self.audioCallEndSemaphore);
            NSLog(@"intptr_t0000:%ld", value);
            value = dispatch_semaphore_signal(self.audioCallEndSemaphore);
            NSLog(@"intptr_t0000:%ld", value);
        });
    });
    
    
    NSLog(@"dispatch_semaphore_wait:---1111");
    intptr_t value = dispatch_semaphore_wait(self.audioCallEndSemaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"intptr_t1111:%ld", value);
    dispatch_async(dispatch_queue_create("dispatch_semaphore_wait:", DISPATCH_QUEUE_CONCURRENT), ^{
        // 子线程消耗信号量后子线程发送信号量
        NSLog(@"dispatch_semaphore_wait:---1111》》》");
        dispatch_semaphore_signal(self.audioCallEndSemaphore);
    });
}
上一篇 下一篇

猜你喜欢

热点阅读