互斥锁--NSCondition

NSCondition

**介绍:**条件锁,是对条件变量和互斥量的封装,互斥量用于保护条件变量的修改,而条件变量实现线程之间的同步。条件既充当当前线程中的锁又充当检查条件,条件锁在执行条件触发的任务时保护临界资源不被其他线程修改,检查条件要求条件在线程继续执行其任务之前为真,条件不成立时,阻塞线程。直到另一个线程向条件对象发出信号为止它都一直保持阻塞状态。

@interface NSCondition : NSObject <NSLocking> {
@private
    void *_priv;
}

- (void)wait;//直到信号量可用,否则让线程进入等待状态
- (BOOL)waitUntilDate:(NSDate *)limit;//阻塞当前线程,直到收到唤醒信号或超时,若高线程被信号唤醒,返回YES,否则返回NO
- (void)signal;//唤醒等待的线程,若要唤醒多个线程,需要调用多次
- (void)broadcast;//唤醒所有等待的线程

@property (nullable, copy) NSString *name;

实现:

1、条件变量的初始化

- (id) init
{
  if (nil != (self = [super init]))
  {
      if (0 != pthread_cond_init(&_condition, NULL))
      {
        DESTROY(self);
      }
      else if (0 != pthread_mutex_init(&_mutex, &attr_reporting))
      {
        pthread_cond_destroy(&_condition);
        DESTROY(self);
      }
    }
  return self;
}

首先,我们分析一下-init方法,该方法先使用pthread_cond_init初始化一个条件变量,初始化成功之后再使用pthread_mutex_init初始化一个锁,如果任何一步初始化失败,都释放资源。

从上面我们可以看出NSCondition的是对条件变量和互斥锁的封装,下面我们看一下条件变量的相关知识。

(1)条件变量的初始化

pthread_cond_init(pthread_cont_t *cv, const pthread_condattr_t *cattr);

cv是指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。结构 pthread_condattr_t是条件变量的属性结构,我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是 PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用,该函数初始化成功返回零,也可以使用静态变量初始化,如下

pthread_cond_t condition = PTHREAD_COND_INITIALIZER;//设置cattr为null的pthread_cond_init()等效

(2)条件变量的销毁

pthread_cond_destroy(pthread_cont_t *cv);

销毁条件变量,但是没有释放存储条件变量的空间

2、阻塞条件变量

(1) - (void) wait

- (void) wait
{
  pthread_cond_wait(&_condition, &_mutex);
}

其中pthread_cond_wait()阻塞当前线程,等待pthread_cond_signal()或pthread_cond_broadcast来唤醒。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait() 函数一进入wait状态就会自动release mutex。当其他线程通过 pthread_cond_signal() 或pthread_cond_broadcast ,把该线程唤醒,使 pthread_cond_wait()通过(返回)时,该线程又自动获得该mutex 。

(2) - (BOOL) waitUntilDate: (NSDate*)limit

- (BOOL) waitUntilDate: (NSDate*)limit
{
  NSTimeInterval ti = [limit timeIntervalSince1970];
  double secs, subsecs;
  struct timespec timeout;
  int retVal = 0;
  // Split the float into seconds and fractions of a second
  subsecs = modf(ti, &secs);
  timeout.tv_sec = secs;
  // Convert fractions of a second to nanoseconds
  timeout.tv_nsec = subsecs * 1e9;
  /* NB. On timeout the lock is still held even through condition is not met
   */
  retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
  if (retVal == 0)
  {
    return YES;
  }
  if (retVal == ETIMEDOUT)
  {
    return NO;
  }
  if (retVal == EINVAL)
  {
    NSLog(@"Invalid arguments to pthread_cond_timedwait");
  }
  return NO;
}

3、解锁

- (void) signal
{
  pthread_cond_signal(&_condition);
}

pthread_cond_signal 函数的作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行.如果没有线程处在阻塞等待状态,pthread_cond_signal也会成功返回。使用pthread_cond_signal一般不会有“惊群现象”产生,他最多只给一个线程发信号。假如有多个线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。但无论如何一个pthread_cond_signal调用最多发信一次。

@interface NSCondition : NSObject <NSLocking>
{
  gs_cond_t	_condition;
  gs_mutex_t	_mutex;
  NSString	*_name;
}

参考:https://www.yuque.com/365cshitou/ontheroad/nscondition?language=en-us

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值