dispatch semaphore.h

版本:iOS13.5

semaphore.h

dispatch其他文件通道

索引

  • dispatch_semaphore_create
    创建新的计数信号量
  • dispatch_semaphore_wait
    等待信号(减少信号量)
  • dispatch_semaphore_signal
    发送信号(增加信号量)

详解

  • 创建新的计数信号量
dispatch_semaphore_t dispatch_semaphore_create(long value);

value 信号量的起始值。
传递小于0的值将导致返回NULL。
当两个线程需要协调特定事件的完成时,将值传递为0。
传递大于0的值对于管理有限的资源池非常有用,其中池的大小等于该值。

  • 等待信号(减少信号量)
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

减少计数信号量。如果结果值小于0,则此函数在返回之前等待发送信号(信号量增加)
可通过dispatch_semaphore_signal来发送信号(增加信号量)
dsema 计数信号量
timeout 超时时间
DISPATCH_TIME_FOREVER 永不超时
DISPATCH_TIME_NOW 立即超时
dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC)自定义超时时间
long 未超时则返回0,如果超时则返回非0

  • 发送信号(增加信号量)
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);

如果先前的值小于0,则此函数在返回之前唤醒等待的线程。
long 如果线程被唤醒,返回非0。否则,返回0。

用法

用法1:锁定当前线程 直到被唤醒
    dispatch_queue_t queue = dispatch_queue_create("data_queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_async(queue, ^{
        NSLog(@"操作1");
        //当前线程在此处等待 直到5秒超时
        long success = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC));
        NSLog(@"dispatch_semaphore_wait %ld", success);
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //使被dispatch_semaphore_wait等待的线程唤醒
        long success = dispatch_semaphore_signal(semaphore);
        NSLog(@"dispatch_semaphore_signal %ld", success);
    });
输出:3秒后发送信号,输出1,表示线程被唤醒。线程唤醒后输出0,表示未超时
操作1
dispatch_semaphore_signal 1
dispatch_semaphore_wait 0
若dispatch_after的3秒改成6秒
则输出:5秒后超时,输出49。6秒后发送信号,由于已经超时,输出0
操作1
dispatch_semaphore_wait 49
dispatch_semaphore_signal 0

用法2:保证数据线程安全
    self.datas = [NSMutableArray array];
    //value为1
    self.semaphore = dispatch_semaphore_create(1);
    dispatch_async(dispatch_get_main_queue(), ^{
       [self lock];
    });
    dispatch_async(dispatch_get_main_queue(), ^{
       [self lock];
    });
- (void)lock {
    //当调用多次lock 第一个lock的dispatch_semaphore_wait使1变成0 此时线程正常运行
    //当第二个lock的dispatch_semaphore_wait使0变成-1 使得第二个lock的线程被暂停
    //第一个lock的datas添加了数据后调用dispatch_semaphore_signal -1变成0 使得第二个lock的线程被唤醒
    //然后第二个lock的datas添加了数据后调用dispatch_semaphore_signal 0变成1 结束
    //此用法可以保证同一时间只能一个线程对数据进行操作
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    [self.datas addObject:@"1"];
    dispatch_semaphore_signal(self.semaphore);
}

你可能感兴趣的:(dispatch semaphore.h)