【问题标题】:pthread_barrier_wait hangs after creation of all threads创建所有线程后 pthread_barrier_wait 挂起
【发布时间】:2015-09-05 15:18:28
【问题描述】:

我正在尝试编写一个简单的程序来使用屏障来等待创建多个线程,然后再从主打印消息。

这是我的代码:

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <cstdlib>
#include <cstdint>

#define NUM_THREADS 8

pthread_barrier_t barrier;

void *threadFun(void *tid)
{
    intptr_t temp = (intptr_t) tid;
    printf("Hello from thread %d\n", temp);
}

int main()
{
    pthread_t threads[NUM_THREADS];
    int rc;
    pthread_barrier_init(&barrier, NULL, NUM_THREADS);

    for(int i = 0; i < NUM_THREADS; ++i) {
        rc = pthread_create(&threads[i], NULL, threadFun, (void *) i);
        if(rc)  {
            printf("Error creating thread %d\n", i);
            exit(-1);
        }
    }

    pthread_barrier_wait(&barrier);
    printf("Hello from main!\n");

    for(int i = 0; i < NUM_THREADS; ++i) {
        pthread_join(threads[i], NULL);
    }
    pthread_barrier_destroy(&barrier);

    return 0;
}

目前,我的程序打印了一些不确定的“Hello from thread”语句,并在打印“Hello from main!”之前挂起;但是,它总是打印 8 条线程消息。因此,创建了所有线程。

为什么还挂着?

【问题讨论】:

  • 是不是省略了threadFun在屏障上等待的部分?
  • @pilcrow 我在threadFunprintf 之前添加了一个pthread_barrier_wait(&amp;barrier);,但它仍然挂起。这次我看到了“来自 main 的你好!”接着是 7 “Hello from thread” 语句。
  • 如果你想让屏障等待你的 8 个工作线程等待主线程,那么屏障需要设置为 9 个线程,而不是 8 个(以及所有线程需要在屏障上等待,但听起来您已经进行了更改)。

标签: c++ multithreading pthreads barrier


【解决方案1】:

屏障预计会被waited NUM_THREADS 次,但只有一个线程,即主线程,实际上调用了pthread_barrier_wait

如果您想将 main 与您的工作线程同步,您需要为 NUM_WORKER_THREADS + 1 初始化屏障。

【讨论】:

    【解决方案2】:
    //  q30941549.cpp
    // https://stackoverflow.com/questions/30941549
    #include <iostream>
    #include <pthread.h>
    #define NUM_THREADS 8
    pthread_barrier_t barrier;
    
    void *threadFun(void *tid) {
      printf("Work done by thread %ld BEFORE the barrier.\n", (long)tid);
      pthread_barrier_wait(&barrier);
      printf("Hello from thread %ld AFTER the barrier.\n", (long)tid);
      pthread_exit(NULL);
    }
    
    int main() {
      pthread_t threads[NUM_THREADS];
      int rc;
      pthread_barrier_init(&barrier, NULL, NUM_THREADS+1);
      for(int i = 0; i < NUM_THREADS; ++i) {
        rc = pthread_create(&threads[i], NULL, threadFun, (void *)(long)i);
        if(rc)  {
          printf("Error creating thread %d\n", i);
          exit(-1);
        }
      }
      printf(" X- - - - - - - - - - - - - - - -X\n");
      printf("main thread BEFORE the barrier.\n");
      printf(" = = BEFORE barrier = BEFORE barrier = =\n");
      pthread_barrier_wait(&barrier);
      printf(" = = AFTER barrier = = AFTER barrier = =\n");
      printf("Hello from main! AFTER the barrier.\n");
      printf(" Y- - - - - - - - - - - - - - - -Y\n");
      for(int i = 0; i < NUM_THREADS; ++i) {
        pthread_join(threads[i], NULL);
      }
      printf("* - * - * - * - * - * - * - * - * - * - * - * - * - *\n");
      printf("This line is ALWAYS last. Only main lives after join.\n");
      return EXIT_SUCCESS;
    }
    

    编译运行:

    g++ -pthread q30941549.cpp && ./a.out # Linux
    g++ -pthread q30941549.cpp && ./a.exe # MSYS2, Windows
    

    如果您尝试运行几次,您可能会看到如下内容:

    Work done by thread 0 BEFORE the barrier.
    Work done by thread 3 BEFORE the barrier.
    Work done by thread 6 BEFORE the barrier.
    Work done by thread 4 BEFORE the barrier.
    Work done by thread 1 BEFORE the barrier.
    Work done by thread 5 BEFORE the barrier.
    Work done by thread 7 BEFORE the barrier.
    Work done by thread 2 BEFORE the barrier.
     X- - - - - - - - - - - - - - - -X
    main thread BEFORE the barrier.
     = = BEFORE barrier = BEFORE barrier = =
     = = AFTER barrier = = AFTER barrier = =
    Hello from main! AFTER the barrier.
     Y- - - - - - - - - - - - - - - -Y
    Hello from thread 6 AFTER the barrier.
    Hello from thread 4 AFTER the barrier.
    Hello from thread 1 AFTER the barrier.
    Hello from thread 5 AFTER the barrier.
    Hello from thread 7 AFTER the barrier.
    Hello from thread 2 AFTER the barrier.
    Hello from thread 0 AFTER the barrier.
    Hello from thread 3 AFTER the barrier.
    * - * - * - * - * - * - * - * - * - * - * - * - * - *
    This line is ALWAYS last. Only main lives after join.
    

    【讨论】:

      猜你喜欢
      • 2013-09-17
      • 2011-04-01
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多