在这次作业中我们将探索如何使用pthread库提供的条件变量来实现1个barrier(屏障)。屏障就是程序中的某一个点必须所有线程都到达才能继续执行。
下载barrier.c,编译并运行。
$ gcc -g -O2 -pthread barrier.c
$ ./a.out 2
Assertion failed: (i == t), function thread, file barrier.c, line 55.
程序的main函数闯将n个线程,每个线程执行1个for循环,在每次循环时assert检测循环次数是否与全局统计值相等,然后调用barrier函数,最后sleep。
for (i = 0; i < 20000; i++) {
int t = bstate.round;
assert (i == t);
barrier();
usleep(random() % 100);
}
我们要实现的就是在barrier函数中确保线程都执行完1次循环才开始下1次循环。增加的代码如下:
pthread_mutex_lock(&bstate.barrier_mutex);
bstate.nthread++;
if (bstate.nthread == nthread) {
bstate.round++;
bstate.nthread = 0;
pthread_cond_broadcast(&bstate.barrier_cond);
}
else {
pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);
}
pthread_mutex_unlock(&bstate.barrier_mutex);
先上锁,增加线程数统计变量barrier.nthread,判断是否已经达到n,如果没有则调用条件变量等待,如果达到了,那么就增加循环次数统计变量barrier.round,同时将barrier.nthread置0,然后广播通知所有线程,唤醒等待中的线程。