【问题标题】:Pthread synchronization with barrier带屏障的 Pthread 同步
【发布时间】:2021-12-02 08:21:51
【问题描述】:

我正在尝试将我正在并行化的函数与 pthread 同步。

问题是,我遇到了死锁,因为一个线程将退出函数,而其他线程仍在等待退出的线程到达屏障。我不确定 pthread_barrier 结构是否能解决这个问题。这是一个例子:

static pthread_barrier_t barrier;

static void foo(void* arg) {

  for(int i = beg; i < end; i++) {
 
    if (i > 0) {

      pthread_barrier_wait(&barrier);

    }

  }

}



int main() {

// create pthread barrier

pthread_barrier_init(&barrier, NULL, NUM_THREADS);

// create thread handles

//...

// create threads

  for (int i = 0; i < NUM_THREADS; i++) {

    pthread_create(&thread_handles[i], NULL, &foo, (void*) i);

  }

// join the threads

  for (int i = 0; i < NUM_THREADS; i++) {

    pthread_join(&thread_handles[i], NULL);

  }

}

这是我为 foo 尝试过的解决方案,但它不起作用(注意 NUM_THREADS_COPY 是 NUM_THREADS 常量的副本,并且每当线程到达函数末尾时递减):

static void foo(void* arg) {

  for(int i = beg; i < end; i++) {

    if (i > 0) {

      pthread_barrier_wait(&barrier);

    }

  }

  pthread_barrier_init(&barrier, NULL, --NUM_THREADS_COPY);

}

当线程退出函数时,是否有更新在屏障中等待的线程数的解决方案?

【问题讨论】:

  • 为什么同时标记为 [c] 和 [c++]?您实际使用的是哪种语言?

标签: c++ c pthreads


【解决方案1】:

您需要确定在任何线程到达之前通过屏障需要多少线程。未定义的行为是由于在有线程等待时重新初始化屏障而导致的。可能的表现包括一些等待线程被过早释放或一些等待线程永远不会被释放,但这绝不是唯一可能发生的不希望的事情。无论如何...

有没有办法更新线程中等待的线程数? 线程退出函数时的障碍?

...不,pthreads 屏障不支持。

由于屏障似乎不够灵活,无法满足您的需求,您可能希望退回到通用线程同步对象:条件变量(与互斥锁和某种共享变量一起使用)。

【讨论】:

  • 另外,OP 可以重新构建循环,以便每个线程执行相同次数的等待 - 如果一个线程要处理的循环迭代次数较少,它可以循环调用 pthread_barrier_wait()弥补差额的正确次数。
猜你喜欢
  • 2013-12-15
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 2023-04-03
  • 2013-08-31
  • 2017-10-19
  • 2016-06-22
相关资源
最近更新 更多