【问题标题】:How to decrement count of barrier on thread completion using pthreads in C如何在 C 中使用 pthreads 减少线程完成时的障碍计数
【发布时间】: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


【解决方案1】:

当屏障像这样使用时,你不能真正改变屏障计数。

问题可能在于,测试跳出循环的条件并非同时适用于所有文件 - 即,每个线程可能执行不同数量的循环。

如果是这种情况,一种解决方案是让每个提前完成的线程继续循环,但除了在每个循环中等待屏障之外什么都不做。然后安排所有线程一起退出 - 像这样:

void* doWork(void* arg)
{
    const char* file = arg;
    int work_done = 0;

    while(1) {
        if (work_done)
        {
            if (all_threads_done)
                break;

            pthread_barrier_wait(&b1);
            continue;
        }

        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
        if (finish_condition)
            work_done = 1;
    }
    return 0;
}

【讨论】:

  • 我得出了同样的结论,但这似乎只是在浪费 cpu 周期,因此正在寻找更高效的东西
猜你喜欢
  • 1970-01-01
  • 2012-10-24
  • 1970-01-01
  • 2018-01-16
  • 2011-04-16
  • 2012-01-05
  • 2023-04-10
  • 2021-11-11
  • 2021-10-30
相关资源
最近更新 更多