阅读 144

信号量dispatch_semaphore的使用注意点

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

  • 控制子线程的并发数:创建时值大于0,最大并发任务数就是并发数。
  • 子线程依赖关系:创建时值传0,当一个异步子线程的任务要等待另一个子线程任务执行完才开始时,需要让后面的任务dispatch_semaphore_wait,前面任务执行完后执行dispatch_semaphore_signal.

代码如下:

// 创建信号量为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);
    });
}

作者:Sweet丶

原文链接:https://www.jianshu.com/p/8d385ec0b920

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐