如何使主线程等待所有子线程完成?

Alc*_*ott 34 c multithreading

我打算在主线程中激活2个线程,并且主线程应该等到所有2个子线程都完成,这就是我的工作方式.

void *routine(void *arg)
{
    sleep(3);
}

int main()
{
    for (int i = 0; i < 2; i++) {
        pthread_t tid;
        pthread_create(&tid, NULL, routine, NULL);
        pthread_join(&tid, NULL);  //This function will block main thread, right?
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,pthread_join确实让主线程等待子线程,但问题是,第二个线程将不会被创建,直到第一个完成.这不是我想要的.

我想要的是,2个线程立即在主线程中创建,然后主线程等待它们完成.似乎pthread_join无法做到这一点,可以吗?

我想,也许通过semaphore我可以做的工作,但任何其他方式?

per*_*eal 60

int main()
{
    pthread_t tid[2];
    for (int i = 0; i < 2; i++) {
        pthread_create(&tid[i], NULL, routine, NULL);
    }
    for (int i = 0; i < 2; i++)
       pthread_join(tid[i], NULL);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的 join 调用来自单个线程,人们喜欢将其称为主线程。所以你的报价不适用。如果您从多个线程调用 pthread_join,那将是另一个故事。请注意,任何生成的踏板都不会超出“例程”。 (2认同)

Bas*_*tch 10

首先创建所有线程,然后加入所有线程:

pthread_t tid[2];

/// create all threads
for (int i = 0; i < 2; i++) {
    pthread_create(&tid[i], NULL, routine, NULL);
}

/// wait all threads by joining them
for (int i = 0; i < 2; i++) {
    pthread_join(tid[i], NULL);  
}
Run Code Online (Sandbox Code Playgroud)

可替代地,有一些pthread_attr_t变量,使用pthread_attr_init(3)然后pthread_attr_setdetachedstate(3) 在其上,然后通过其地址来在pthread_create(3)第二个参数.Thos会以分离状态创建线程.或者pthread_detach按照Jxh的回答中的说明使用.

  • 主要问题是 pthread_join() 会阻塞,因此如果您有 512 个线程每运行 10 小时 +/- 5 小时,线程 1-511 将不会被连接,直到线程 0 完成。其中之一可能会更早结束。我也不确定在很多情况下分离它们是否有用。如果时间或多或少恒定,我们可以将创作错开 2 分钟的延迟。 (3认同)

jxh*_*jxh 6

您可以分离地启动线程,而不用担心加入。

for (int i = 0; i < 2; i++) {
    pthread_t tid;
    pthread_create(&tid, NULL, routine, NULL);
    pthread_detach(tid);
}
pthread_exit(0);
Run Code Online (Sandbox Code Playgroud)

或者,您可以让死亡的线程向主线程报告它是谁,以便线程按照它们退出的顺序而不是按照您创建它们的顺序加入。

void *routine(void *arg)
{
    int *fds = (int *)arg;
    pthread_t t = pthread_self();
    usleep((rand()/(1.0 + RAND_MAX)) * 1000000);
    write(fds[1], &t, sizeof(t));
}

int main()
{
    int fds[2];
    srand(time(0));
    pipe(fds);
    for (int i = 0; i < 2; i++) {
        pthread_t tid;
        pthread_create(&tid, NULL, routine, fds);
        printf("created: %llu\n", (unsigned long long)tid);
    }
    for (int i = 0; i < 2; i++) {
        pthread_t tid;
        read(fds[0], &tid, sizeof(tid));
        printf("joining: %llu\n", (unsigned long long)tid);
        pthread_join(tid, 0);
    }
    pthread_exit(0);
}
Run Code Online (Sandbox Code Playgroud)