如何在 C 中使用 pthreads 减少线程完成时的屏障计数

How to decrement count of barrier on thread completion using pthreads in C

我有一个函数:createrWorkerPool,它将产生 "n" 个工作线程,每个工作线程都将输入作为参数中指定的文件 pthread_create,读取文件通过使用修改共享变量围绕它的互斥量并在屏障处等待,直到所有线程都完成修改其共享变量。这个操作在循环中发生了很多次。

我面临的问题是让我们考虑有两个文件 file1 和 file2,file2 的大小比 file1 大得多。屏障同步一直工作到 file1 完成 - 但由于它完成执行,它不再到达屏障并且 file2 永远卡在屏障中。

我的问题是,有没有一种方法可以在线程退出时动态更改屏障正在等待的线程数。所以在上述情况下,如果 file1 提前完成,它会将屏障计数从 2 减少到 1,以便 file1 可以继续执行。我试着查看手册页,但没有看到任何 function.Example 代码

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

所以基本上 thread1 操作 file1 之前完成并且 thread2 永远停留在障碍处

当屏障正在使用时,您无法真正更改屏障计数。

据推测,问题是测试跳出循环的条件对于所有文件在同一时间并不成立 - 即,每个线程可能执行不同数量的循环。

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

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