我在C ++中运行它,但是我认为相同的代码可以在C中运行。我对障碍的理解是,当你使用pthread_barrier_init()时,你给它一个数字。该数字表示在任何线程被解除阻塞之前必须调用pthread_barrier_wait()的线程数。所以基本上如果数字是4并且你有3个线程到目前为止执行了wait()行,那么所有3个线程都将被阻塞,直到第4个线程出现并调用pthread_barrier_wait()。
我试图让所有线程同时开始执行。
#include <pthread.h>
#include <stdio.h>
void* thread_func(void* args) {
pthread_barrier_t *barrier = (pthread_barrier_t*)args;
printf("waiting for barrier\n");
pthread_barrier_wait(barrier);
printf("passed barrier\n");
return NULL;
}
int main() {
int const num_threads = 4;
pthread_t threads[num_threads];
pthread_barrier_t *barrier;
pthread_barrier_init(barrier, NULL, num_threads);
int i;
for (i = 0; i < num_threads; i++) {
pthread_create(&threads[i], NULL, thread_func, (void*)barrier);
}
for (i = 0; i < num_threads; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
我收到的输出:
waiting for barrier
waiting for barrier
waiting for barrier
passed barrier
passed barrier
passed barrier
waiting for barrier
passed barrier
输出我期望:
waiting for barrier
waiting for barrier
waiting for barrier
waiting for barrier
passed barrier
passed barrier
passed barrier
passed barrier
另一个非常奇怪的事情是,在我的pthread_barrier_init(barrier,NULL,num_threads)调用中,我可以将数字更改为(num_threads + 40)并且程序仍然运行。我认为在这种情况下,在这种情况下,所有的线程都将永远坐在他们的wait()调用中,因为永远不会有num_threads + 40个线程在等待。
我错过了什么?
答案 0 :(得分:4)
pthread_barrier_t *barrier;
pthread_barrier_init(barrier, NULL, num_threads);
所以barrier
是一个永远不会指向任何东西的指针。您永远不会为barrier
分配值,但会将其值传递给pthread_barrier_init
。所以pthread_barrier_init
获取垃圾值,你的线程也是如此。
在某个地方,你需要创建一个实际的障碍,而不仅仅是一个指针。
你可以这样做:
pthread_barrier_t actual_barrier;
pthread_barrier_t *barrier = &actual_barrier;
pthread_barrier_init(barrier, NULL, num_threads);
这实际上会创建一个障碍并将其地址传递给pthread_barrier_init
,因此可以初始化您实际创建的障碍。
答案 1 :(得分:1)
@DavidSchwartz给出的答案增加了一条额外的行,以使指针形式清楚如何需要指向pthread_barrier_t
的实际实例。但是,对于非常本地化的用法,更典型的是:
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, num_threads);