美文网首页
互斥量与信号量

互斥量与信号量

作者: conowen | 来源:发表于2018-05-09 17:12 被阅读12次

    互斥量 (Mutex)

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制。

    在iOS中,实现互斥量有多种方式,一般有

    • @synchronized 同步代码快
    @synchronized(self) {
    // task
    }
    
    • NSLock 对象锁
      NSLock *mutexLock = [[NSLock alloc] init];
      [mutexLock lock];
      //task
      [mutexLock unlock];
    
    • NSRecursiveLock 递归锁
      NSLock在递归中容易产生死锁,使用NSRecursiveLock可以避免这个问题

    • NSConditionLock 条件锁
      满足预设的条件,就可以获取锁

    • OSSpinLock 自旋锁
      一般的互斥锁没有拿到锁之前,线程都会休眠,而自旋锁不会引起调用者线程休眠,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁。

    • pthread_mutex C语言实现的互斥锁

    信号量(Semaphore)

    信号量是一个同步对象,用于保持在0至指定最大值之间的一个计数值。当线程完成一次对该semaphore对象的等待(wait)时,该计数值(- 1);当线程完成一次对semaphore对象的释放(release)时,计数值(+ 1)。简单来说,信号量为0的时候,线程会阻塞,一直等待该信号量对象的计数值变成大于0的状态。

      dispatch_queue_t queue = 
      dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
      dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);//信号量初始为0
      dispatch_async(queue, ^{
          // task1
          dispatch_semaphore_signal(semaphore);// 使信号量+1并返回
      });
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
      // task2 
      //只有当task1执行完,信号量+1之后,才会执行这里
    
    

    数值为N的信号量允许N个线程并发访问。

    如果信号量是一个任意的整数,通常被称为计数信号量(Counting semaphore),或一般信号量(general semaphore);如果信号量只有二进制的0或1,称为二进制信号量(binary semaphore)。在linux系统中,二进制信号量(binary semaphore)又称互斥量(Mutex)。

    所以说,互斥量和信号量本质上一样,都是用来表示对资源的访问权,但是互斥量表示资源某个时刻最多只能被一个线程占用,也就是资源计数最多是1,而信号量的资源计数可以超过1,即同时被多个线程占用。

    两者对比的话,简单来说,

    • 互斥量就是N个线程,争夺一把锁,
    • 信号量就是N个线程,争夺M把锁,当信号量的计数值只有0、1(二进制信号量),那么M = 1,这时候,和互斥量的性质是一样的。

    参考文章

    https://zh.wikipedia.org/wiki/%E4%BF%A1%E8%99%9F%E6%A8%99

    相关文章

      网友评论

          本文标题:互斥量与信号量

          本文链接:https://www.haomeiwen.com/subject/uwwnrftx.html