gpt4 book ai didi

c - 如何在障碍处正确同步线程

转载 作者:行者123 更新时间:2023-12-05 09:31:11 24 4
gpt4 key购买 nike

我遇到了一个问题,我很难确定我应该使用哪个同步原语。

我正在创建 n 个在内存区域上工作的并行线程,每个线程都分配给该区域的特定部分,并且可以独立于其他线程完成其任务。在某些时候,我需要收集所有线程的工作结果,这是使用屏障的一个很好的例子,这就是我正在做的事情。

我必须使用 n 个工作线程之一来收集它们所有工作的结果,为此我在线程函数中的计算代码之后有以下代码:

if (pthread_barrier_wait(thread_args->barrier)) {
// Only gets called on the last thread that goes through the barrier
// This is where I want to collect the results of the worker threads
}

到目前为止一切顺利,但现在是我卡住的地方:上面的代码处于循环中,因为我希望线程在一定数量的循环旋转中再次完成工作。这个想法是每次 pthread_barrier_wait 解除阻塞意味着所有线程都完成了他们的工作并且循环的下一次迭代/并行工作可以重新开始。

问题在于结果收集器 block 语句不能保证在其他线程再次开始在此区域上工作之前执行,因此存在竞争条件。我正在考虑使用这样的 UNIX 条件变量:

// This code is placed in the thread entry point function, inside
// a loop that also contains the code doing the parallel
// processing code.

if (pthread_barrier_wait(thread_args->barrier)) {
// We lock the mutex
pthread_mutex_lock(thread_args->mutex);
collectAllWork(); // We process the work from all threads
// Set ready to 1
thread_args->ready = 1;
// We broadcast the condition variable and check it was successful
if (pthread_cond_broadcast(thread_args->cond)) {
printf("Error while broadcasting\n");
exit(1);
}
// We unlock the mutex
pthread_mutex_unlock(thread_args->mutex);
} else {
// Wait until the other thread has finished its work so
// we can start working again
pthread_mutex_lock(thread_args->mutex);
while (thread_args->ready == 0) {
pthread_cond_wait(thread_args->cond, thread_args->mutex);
}
pthread_mutex_unlock(thread_args->mutex);
}

这有多个问题:

  • 出于某种原因,pthread_cond_broadcast 从未解锁等待 pthread_cond_wait 的任何其他线程,我不知道为什么。
  • 如果线程pthread_cond_wait收集器线程广播后会发生什么情况?我相信 while (thread_args->ready == 0)thread_args->ready = 1 可以防止这种情况,但接下来请看下一点...
  • 在下一个循环中,ready 仍将设置为 1,因此没有线程会再次调用 pthread_cond_wait。我看不到任何可以将 ready 正确设置回 0 的地方:如果我在 pthread_cond_wait 之后的 else block 中执行此操作,则有即使我已经从 if block 广播,另一个尚未等待的线程读取 1 并开始等待的可能性。

请注意,我需要为此使用障碍。

我该如何解决这个问题?

最佳答案

您可以使用两个障碍(工作和收集器):

while (true) {

//do work

//every thread waits until the last thread has finished its work
if (pthread_barrier_wait(thread_args->work_barrier)) {
//only one gets through, then does the collecting
collectAllWork();
}

//every thread will wait until the collector has reached this point
pthread_barrier_wait(thread_args->collect_barrier);

}

关于c - 如何在障碍处正确同步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69008816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com