3

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

这是我的代码:

#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 条线程消息。因此,创建了所有线程。

为什么还挂着?

4

2 回答 2

4

屏障预计会wait在 NUM_THREADS 次上被编辑,但只有一个线程,主线程,实际调用pthread_barrier_wait.

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

于 2015-06-19T16:25:12.483 回答
0
//  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.
于 2020-11-28T12:43:19.227 回答