如何确保在同一个函数终止之前在函数 return 中创建的所有线程?

How do I secure that all threads created in a function return before the very same function terminates?

考虑 C 函数的以下部分:

for (int i = 0; i < n; ++i) {
    thread_arg *arg = (thread_arg *) malloc(sizeof(thread_arg));
    arg->random_value = random_value;
    arg->message = &(message[i * 10]);

    if (pthread_create(NULL, NULL, thread_start, (void *) &arg)) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }
}

在这个 for 循环中,我创建了 n 个线程,它们都执行具有不同参数的通用例程。这个 for 循环是一个更大的函数的一部分,这个函数 return 是一个数据结构,它被所有线程并行修改。因此,重要的是这个更大的函数不会在所有线程完成之前 return。
我希望找到一种更简单的方法,然后为所有这些线程提供一个单独的 ID,然后使用 pthread_join 加入。
是否有任何通用的方法来对类似 "hey, don't return until all threads you've created returned" 的函数说?

至少还有两种方式:

  1. 使用 pthread 障碍。名称屏障的使用意义与您在谈论并发时通常听到的意义完全不同。在这里,它是一个同步原语,它让一组线程(其上的等待者)中的每一个都阻塞,直到所有线程都到达它,然后将它们一起解除阻塞。您首先在某个共享位置初始化屏障,并将 n+1 作为计数,然后让函数本身和它创建的所有 n 线程在完成之前调用 pthread_barrier_wait。假设你这样做,在等待 return 之后,n 线程不能再访问共享状态;他们需要立即 return.

  2. 使用 condvar 和 mutex 创建相同的东西(或它的简化版本)。统计 n 线程中有多少仍在工作,并受互斥锁保护。然后创建它们的函数可以做:

    pthread_mutex_lock(&cnt_mtx);
    while (count > 0) pthread_cond_wait(&cnt_cv, &cnt_mtx);
    pthread_mutex_unlock(&cnt_mtx);
    

不过,一般来说,我会在这里使用 pthread_join。这就是它的用途。