【问题标题】:pthread_barrier not behaving how I'd expectpthread_barrier 没有表现出我的预期
【发布时间】:2018-02-22 19:34:18
【问题描述】:

我在 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 个线程在等待。

我错过了什么?

【问题讨论】:

    标签: c multithreading pthreads


    【解决方案1】:
    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,因此可以初始化您实际创建的屏障。

    【讨论】:

      【解决方案2】:

      @DavidSchwartz 给出的答案增加了一行,以明确指针形式需要如何指向pthread_barrier_t 的实际实例。然而,对于非常本地化的使用来说,更典型的是:

      pthread_barrier_t barrier;
      pthread_barrier_init(&barrier, NULL, num_threads);
      

      【讨论】:

        猜你喜欢
        • 2019-07-22
        • 1970-01-01
        • 2019-08-25
        • 1970-01-01
        • 2021-09-14
        • 1970-01-01
        • 1970-01-01
        • 2013-10-18
        • 1970-01-01
        相关资源
        最近更新 更多