OC信号量的基本使用

信号量

dispatch_semaphore_create(long value);

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

dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

  • desema: 信号量。 在此参数中传递NULL的结果是未定义的。
  • timeout: 何时超时(请参阅dispatch_time)。 为方便起见,有DISPATCH_TIME_NOW和DISPATCH_TIME_FOREVER常量。
  • des: 减少计数信号量。 如果结果值小于零,则此函数在返回之前等待信号发生。
  • returned: 成功时返回零,如果超时,则返回非零。

dispatch_semaphore_signal(dispatch_semaphore_t dsema);

  • desma: 信号量。 在此参数中传递NULL的结果是未定义的。
  • des: 增加计数信号量。 如果前一个值小于零,则此函数在返回之前唤醒等待的线程。
  • returned:如果线程被唤醒,则此函数返回非零值。 否则,返回零。

用法

控制线程数量

  • 可以限制线程的并发数量
 self.signal = dispatch_semaphore_create(10);
    for (int i = 0; i < 1000; i++) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(self.signal, DISPATCH_TIME_FOREVER); //信号量-1
            //...耗时操作
            dispatch_semaphore_signal(self.signal);// 信号量+1
        });
        
    }

等待异步回调(强行同步代码块)

  • 强行同步某些操作,例如在子线程内等待异步block调用完成,同步获取Block内的回调结果。
    dispatch_async(self.queue, ^{
        self.signal = dispatch_semaphore_create(1); //只允许一个信号量
        int a = 0;        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //开启一个耗时的异步Block
            //异步的耗时操作,比如:睡眠3秒
            [NSThread sleepForTimeInterval:3];
            a = 1;
            dispatch_semaphore_signal(self.signal);//释放信号量
        });
        dispatch_semaphore_wait(self.signal, DISPATCH_TIME_FOREVER); //锁住信号量
        //等待异步回调完成后的操作。
      NSLog(@"current a :%ld",(long)a);
    });

其他语言相似的地方.

  • golang的 waitgroup使用类似。
  • java的notify,wait机制类似。

注意事项:不要轻易在主线程调用wait方法。在信号量小于0的情况下绝对会锁住当前主线程。

你可能感兴趣的:(OC信号量的基本使用)