【问题标题】:C/POSIX- pthread_t's blocking until task completionC/POSIX-pthread_t 的阻塞直到任务完成
【发布时间】:2013-02-03 00:08:13
【问题描述】:

我有一组 pthreads,它们都需要完成一个任务,然后阻塞直到它们中的最后一个完成任务,然后让它们全部移动到下一个任务。许多任务都会发生这种情况。

我正在考虑有一个计数器,它开始等于每个任务开始时的线程数,当每个线程完成一个任务时,它会使用互斥锁安全地递减它,直到最后一个线程使其为零。在任务结束时,除了最后一个要完成的线程之外的所有线程都会调用 pthread_cond_wait,最后一个线程会调用 pthread_cond_broadcast 告诉其他线程进入下一个任务。然后最后一个线程不会等待,而是继续执行此任务。

但是,我还有一个问题。不能保证倒数第二个递减计数器的线程会在最后一个线程调用 pthread_cond_broadcast 之前调用 pthread_cond_wait。

在 C 和 POSIX 中有什么方法可以安全地处理这个问题吗?

【问题讨论】:

  • 即使你已经找到了使用屏障的解决方案,这句话让我有点困扰:“不能保证倒数第二个减少计数器的线程会在最后一个线程调用 pthread_cond_broadcast 之前调用 pthread_cond_wait ”。如果您正确使用条件变量,则倒数第二个线程和最后一个线程之间不能竞争以递减计数器,因为倒数第二个线程在调用pthread_cond_wait() 时应该持有互斥锁。您关心的问题是您在调用pthread_cond_wait() 时必须持有互斥锁的原因。
  • 是的,我现在明白了,Sheu 的解决方案向我指出了这一点。

标签: c multithreading pthreads posix


【解决方案1】:

您正在寻找的工具是障碍。

用等待到达它的线程数初始化屏障:

pthread_barrier_init(&barrier, NULL, N);

然后,每个线程调用:

pthread_barrier_wait(&barrier);

等待会阻塞,直到 N 个线程在其上等待,然后所有 N 个(从概念上)唤醒,然后它们中的任何一个从等待调用返回。

【讨论】:

  • 这正是我要找的东西。非常感谢!
  • 刚刚实现,只需很少的代码即可完美运行。谢谢!
  • 我喜欢障碍。它们是我最喜欢的 pthreads 中使用最少的原语。它们有一些非常好的用途(N=2)用于在父线程和新创建的线程之间进行通信以进行参数传递等。
【解决方案2】:

我想你正在寻找pthread_join


edit:我猜你是想不破坏线程。

pthread_cond_wait 应该与互斥锁一起使用,例如:

int counter;                      // initialized to number of threads
struct pthread_cond_t condition;  // initialized previously
struct pthread_mutex_t mutex;     // initialized previously

pthread_mutex_lock(&mutex);
counter -= 1;
while (counter > 0)
    pthread_cond_wait(&condition, &mutex);
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&mutex);

这将处理锁定、计数器和条件,而无需使用单独的信号量。 (您实际上是在实现某种“反向信号量”。)

【讨论】:

  • 太好了,我现在明白了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2010-12-04
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多