Подтвердить что ты не робот

Как заставить основной поток ждать завершения всех дочерних потоков?

Я намерен запустить 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?
    }
}

В приведенном выше коде pthread_join действительно заставляет основной поток ждать дочерних потоков, но проблема в том, что второй поток не будет создан до завершения первого. Это не то, что я хочу.

Я хочу, чтобы 2 потока создавались сразу в основном потоке, а затем основной поток ждет их завершения. Кажется, что pthread_join не может сделать трюк, не так ли?

Я подумал, может быть, через semaphore я могу выполнить эту работу, но любым другим способом?

4b9b3361

Ответ 1

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

Ответ 2

Сначала создайте все потоки, затем присоедините их все:

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

В качестве альтернативы, используйте переменную pthread_attr_t, используйте pthread_attr_init (3), затем pthread_attr_setdetachedstate (3) затем перейдите к pthread_create (3) второй аргумент. Thos создаст потоки в отдельном состоянии. Или используйте pthread_detach, как описано в Jxh answer.

Ответ 3

Вы можете начать отключать потоки и не беспокоиться о присоединении.

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

Или, альтернативно, вы можете иметь поток, который умирает, сообщать основному потоку, кто он, так что потоки соединяются в том порядке, в котором они выходили, а не в том порядке, в котором вы их создали.

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