线程屏障(基于linuxthreads-2.3)

线程屏障是线程同步的一个方式。线程执行完一个操作后,可能需要等待其他线程也完成某个动作,这时候,当前该线程就会被挂起,直到其他线程也完成了某个操作,最后所有线程被唤醒。屏障主要有三个函数。

int
pthread_barrier_wait(pthread_barrier_t *barrier)
{
  pthread_descr self = thread_self();
  pthread_descr temp_wake_queue, th;
  int result = 0;

  __pthread_lock(&barrier->__ba_lock, self);

  /* If the required number of threads have achieved rendezvous... */
  // pthread_barrier_wait被调用的次数达到阈值,__ba_present + 1 == __ba_required 
  if (barrier->__ba_present >= barrier->__ba_required - 1)
    {
      /* ... then this last caller shall be the serial thread */
      result = PTHREAD_BARRIER_SERIAL_THREAD;
      /* Copy and clear wait queue and reset barrier. */
      // 被阻塞的线程队列
      temp_wake_queue = barrier->__ba_waiting;
      // 重置字段
      barrier->__ba_waiting = NULL;
      barrier->__ba_present = 0;
    }
  else
    {
      result = 0;
      // 执行pthread_barrier_wait一次,加一
      barrier->__ba_present++;
      // 插入等待队列
      enqueue(&barrier->__ba_waiting, self);
    }

  __pthread_unlock(&barrier->__ba_lock);
  // 调用pthread_barrier_wait的次数还不够
  if (result == 0)
    {
      /* Non-serial threads have to suspend */
      // 挂起当前线程
      suspend(self);
      /* We don't bother dealing with cancellation because the POSIX
         spec for barriers doesn't mention that pthread_barrier_wait
         is a cancellation point. */
    }
  else
    {
      /* Serial thread wakes up all others. */
      // 唤醒其他的线程
      while ((th = dequeue(&temp_wake_queue)) != NULL)
  restart(th);
    }

  return result;
}

int
pthread_barrier_init(pthread_barrier_t *barrier,
        const pthread_barrierattr_t *attr,
        unsigned int count)
{
  if (count == 0)
     return EINVAL;

  __pthread_init_lock(&barrier->__ba_lock);
  // 需要执行pthread_barrier_wait的次数
  barrier->__ba_required = count;
  // 已经调用pthread_barrier_wait的次数
  barrier->__ba_present = 0;
  // 调用pthread_barrier_wait被阻塞的线程队列
  barrier->__ba_waiting = NULL;
  return 0;
}

int
pthread_barrier_destroy(pthread_barrier_t *barrier)
{
  // 有线程在等待
  if (barrier->__ba_waiting != NULL) return EBUSY;
  return 0;
}

从代码里我们知道,屏障的本质就是计数,还没有达到某个数的时候,当前线程就被阻塞,等到最后一个线程执行pthread_barrier_wait函数并且得到了某个数的时候,全部线程被唤醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值