2013-02-03 42 views
0

我有一组并行线程,所有需要完成的任务,然后阻塞,直到最后一个人完成任务,然后让所有的人都移动到下一个任务。这发生在许多任务上。C/POSIX-的pthread_t的阻塞,直到任务完成

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

不过,我留下了一个问题。不能保证第二个到最后一个线程递减计数器将在最后一个线程调用pthread_cond_broadcast之前调用pthread_cond_wait。

有没有办法在C和POSIX安全地处理呢?

+0

即使你已经找到了解决办法使用的障碍,这句话令我烦恼了一下:“有没有保证,倒数第二个线程递减计数器将调用调用pthread_cond_wait最后一个线程调用调用pthread_cond_broadcast之前”。如果你正确地使用了条件变量,那么倒数第二个和最后一个线程之间就不会有竞争,因为倒数第二个线程在调用pthread_cond_wait()时应该保持互斥体。你担心的问题是你在调用'pthread_cond_wait()'时必须保持互斥体的原因。 –

+0

是的,我现在明白了,Sheu的解决方案向我指出了这一点。 –

回答

3

你要找的工具是障碍。

初始化与将要等待到达它的线程数的障碍:

pthread_barrier_init(&barrier, NULL, N); 

然后,每个线程的调用:

pthread_barrier_wait(&barrier); 

等待阻塞,直到N个线程正在等待在其上,然后所有的N都在唤醒之前(概念上)在他们中的任何一个从等待电话返回之前。

+0

这就是我正在寻找的东西。非常感谢! –

+0

刚刚实现了它,只用很少的代码完美工作。谢谢! –

+0

我喜欢壁垒。它们是我在pthread中最喜欢的最小努力使用原语。他们有一些非常好的用途(N = 2)用于在父线程和新创建的线程之间进行参数传递等。 –

1

我认为你正在寻找pthread_join


编辑:我想你想不破坏线程。

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); 

这将照顾锁定,计数器,和条件的,而无需使用单独的信号量。 (你基本上实现各种各样的“反向信号”。)

+0

太棒了,我现在明白了。谢谢! –

相关问题