前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线程屏障(基于linuxthreads-2.3)

线程屏障(基于linuxthreads-2.3)

作者头像
theanarkh
修改2019-10-22 20:46:18
4760
修改2019-10-22 20:46:18
举报
文章被收录于专栏:原创分享原创分享

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

代码语言:javascript
复制
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函数并且得到了某个数的时候,全部线程被唤醒。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程杂技 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档