【发布时间】:2016-05-12 03:06:26
【问题描述】:
我有一个函数:createrWorkerPool,它将产生“n”个工作线程,每个工作线程都将输入作为 pthread_create 的 args 中指定的文件,读取文件通过使用它周围的互斥体修改共享变量并等待障碍,直到所有线程都完成了对其共享变量的修改。此操作在循环中发生很多次。
我面临的问题是,让我们考虑有两个文件 file1 和 file2,而 file2 的大小比 file1 大得多。屏障同步一直有效,直到 file1- 完成,但由于它完成执行,它不再到达屏障,并且 file2 永远卡在屏障中。
我的问题是,有没有办法在线程退出时动态更改屏障正在等待的线程数。因此在上述情况下,如果 file1 提前完成,它会将屏障计数从 2 减少到 1,以便 file1 可以继续执行。我尝试查看手册页,但没有看到任何功能。示例代码
pthread_mutex_t m1;
pthread_barrier_t b1;
//common function executed by each worker thread
void* doWork(void* arg) {
const char* file = arg;
while(1) {
pthread_mutex_lock(&m1);
// Modify shared variable
pthread_mutex_unlock(&m1);
// Wait for all threads to finish modifying shared variable
pthread_barrier_wait(&b1);
// Once all threads reach barrier check state of shared variable and do some task based on state
// check for condition if true break out of loop
}
return 0;
}
所以基本上线程 1 操作文件 1 之前完成,线程 2 永远卡在屏障上
【问题讨论】:
-
程序的结构并不完全清楚。每个文件的循环次数是否与其他文件相同?
-
问题已编辑以反映清晰的想法
-
这个来源很难理解,很多细节都没有在你的问题文本中解释。是什么阻止了两个线程到达
pthread_barrier_wait()?程序的实际结构尚不清楚。我不确定为什么doWork()和pthread_barrier_wait()中都有一个循环,因为我希望每个工作线程在需要执行需要共享变量的任务时都会调用doWork()函数。那么doWork()函数不应该执行以下操作:检查共享变量、打开指定的文件、执行操作、返回吗? -
至于改变barrier数量你可以使用
pthread_barrier_init()初始化barrier,pthread_barrier_wait()等待所有线程到达barrier,然后pthread_barrier_destroy()使用后销毁barrier .然后只需创建一个新的。见pthread_barrier_init(3) - Linux man page。另请参阅docs.oracle.com/cd/E19253-01/816-5137/gfwek/index.html,有关示例,请参阅threads/pthread_barrier_demo.c。 -
我不确定屏障的确切用途,但对于您的 cmets,您已考虑使用信号量而不是屏障?
标签: c multithreading pthreads