简体   繁体   English

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

[英]How to make main thread wait for all child threads finish?

I intend to fire 2 threads in the main thread, and the main thread should wait till all the 2 child threads finish, this is how I do it.我打算在主线程中触发 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?
    }
}

In the above code, pthread_join indeed makes main thread wait for the child threads, but the problem is, the second thread won't be created untill the first one finishes.在上面的代码中, pthread_join确实让主线程等待子线程,但问题是,直到第一个线程完成后,第二个线程才会被创建。 This is not what I want.这不是我想要的。

What I want is, the 2 threads get created immediatly in the main thread, and then main thread waits for them to finish.我想要的是,这 2 个线程在主线程中立即创建,然后主线程等待它们完成。 Seems like pthread_join cannot do the trick, can it?似乎pthread_join不能解决问题,是吗?

I thought, maybe via a semaphore I can do the job, but any other way?我想,也许通过semaphore我可以完成这项工作,但还有其他方法吗?

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

First create all the threads, then join all of them:首先创建所有线程,然后加入所有线程:

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

Alternatively, have some pthread_attr_t variable, use pthread_attr_init(3) then pthread_attr_setdetachedstate(3) on it, then pass its address to pthread_create(3) second argument.或者,有一些pthread_attr_t变量,使用pthread_attr_init(3)然后pthread_attr_setdetachedstate(3)在它上面,然后将它的地址传递给pthread_create(3)第二个参数。 Thos would create the threads in detached state. Thos 将创建处于分离状态的线程。 Or use pthread_detach as explained in Jxh's answer .或者按照Jxh 的回答中的说明使用pthread_detach

Remember to read some good Pthread tutorial .记得阅读一些不错的Pthread 教程 You may want to use mutexes and condition variables.您可能想要使用互斥量和条件变量。

You could use frameworks wrapping them, eg Qt or POCO (in C++), or read a good C++ book and use C++ threads .您可以使用包装它们的框架,例如QtPOCO (在 C++ 中),或者阅读一本好的C++ 书籍并使用C++ 线程

Conceptually, threads have each their call stack and are related to continuations .从概念上讲,线程都有自己的调用堆栈,并且与continuations相关。 They are "heavy".他们很“重”。

Consider some agent-oriented programming approach: as a rule of thumb, you don't want to have a lot of threads (eg 20 threads on a 10 core processor is reasonable, 200 threads won't be unless a lot of them are sleeping or waiting) and and do want threads to synchronize using mutex and condition variables and communicate and/or synchronize with other threads quite often (several times per second).考虑一些面向代理的编程方法:根据经验,您不希望有很多线程(例如, 10 核处理器上的 20 个线程是合理的,除非有很多线程在休眠,否则 200 个线程不会或等待)并且确实希望线程使用互斥锁和条件变量进行同步,并经常与其他线程通信和/或同步(每秒几次)。 See also poll(2) , fifo(7) , unix(7) , sem_overview(7) with shm_overview(7) as another way of communicating between threads.另请参阅poll(2)fifo(7)unix(7)sem_overview(7)shm_overview(7)作为线程间通信的另一种方式。 In general, avoid using signal(7) with threads (read signal-safety(7) ...), and use dlopen(3) with caution (probably only in the main thread).通常,避免在线程中使用signal(7) (阅读signal-safety(7) ...),并谨慎使用dlopen(3) (可能只在主线程中使用)。

A pragmatical approach would be to have most of your threads running some event loop (using poll(2) , pselect(2) , perhaps eventfd(2) , signalfd(2) , ....), perhaps communicating using pipe(7) or unix(7) sockets.一种实用的方法是让你的大部分线程运行一些事件循环(使用poll(2)pselect(2) ,也许是eventfd(2)signalfd(2) ......),也许使用pipe(7 ) 进行通信)unix(7)套接字。 See also socket(7) .另见socket(7)

Don't forget to document (on paper) the communication protocols between threads.不要忘记记录(在纸上)线程之间的通信协议。 For a theoretical approach, read books about π-calculus and be aware of Rice's theorem : debugging concurrent programs is difficult.对于理论方法,请阅读有关π 演算的书籍并了解莱斯定理:调试并发程序很困难。

You could start the threads detached, and not worry about joining.您可以启动线程分离,而不用担心加入。

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

Or, alternatively, you can have the thread that dies report back to the main thread who it is, so that the threads are joined in the order they exited, rather than in the order you created them in.或者,您可以让死掉的线程向主线程报告它是谁,这样线程就会按照它们退出的顺序加入,而不是按照您创建它们的顺序。

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);
}
#include<stdio.h>
#include<pthread.h>

int icnt = 0;   //in non_bss data segment
pthread_mutex_t lock;     //lock variable created stored into bss data segment


void *Thread_count(void* args)      //syncronization 
{
pthread_mutex_lock(&lock);              //lock aquire 
    
icnt++;

for(int x = 1; x <= icnt; x++)
{
    printf("Hello from Thread_count : %d \n",icnt);
}
printf("\n");

pthread_mutex_unlock(&lock);            //release lock  
pthread_exit(NULL);                     //exit from child thread
}


int main()
{

pthread_t threads[4];  //created array of {unsigned long int}
int status = 0;

//creating threads in loop      
for(int i = 1; i <= sizeof(threads)/sizeof(threads[0]); i++)
{
    pthread_create(&threads[i], NULL, &Thread_count, NULL);
}

//waiting for threads in loop
for(int j = 1; j <= sizeof(threads)/sizeof(threads[0]); j++)
{
    pthread_join(threads[j], &status);
    
    printf("Thread number : %d     <-->  Thread status : %d\n",j, status);
}


pthread_exit(0);  //end of main thread
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM