[英]How to make main thread wait for all child threads finish?
我打算在主线程中触发 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?
}
}
在上面的代码中, pthread_join
确实让主线程等待子线程,但问题是,直到第一个线程完成后,第二个线程才会被创建。 这不是我想要的。
我想要的是,这 2 个线程在主线程中立即创建,然后主线程等待它们完成。 似乎pthread_join
不能解决问题,是吗?
我想,也许通过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;
}
首先创建所有线程,然后加入所有线程:
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 将创建处于分离状态的线程。 或者按照Jxh 的回答中的说明使用pthread_detach
。
记得阅读一些不错的Pthread 教程。 您可能想要使用互斥量和条件变量。
您可以使用包装它们的框架,例如Qt或POCO (在 C++ 中),或者阅读一本好的C++ 书籍并使用C++ 线程。
从概念上讲,线程都有自己的调用堆栈,并且与continuations相关。 他们很“重”。
考虑一些面向代理的编程方法:根据经验,您不希望有很多线程(例如, 10 核处理器上的 20 个线程是合理的,除非有很多线程在休眠,否则 200 个线程不会或等待)并且确实希望线程使用互斥锁和条件变量进行同步,并经常与其他线程通信和/或同步(每秒几次)。 另请参阅poll(2) 、 fifo(7) 、 unix(7) 、 sem_overview(7)和shm_overview(7)作为线程间通信的另一种方式。 通常,避免在线程中使用signal(7) (阅读signal-safety(7) ...),并谨慎使用dlopen(3) (可能只在主线程中使用)。
一种实用的方法是让你的大部分线程运行一些事件循环(使用poll(2) 、 pselect(2) ,也许是eventfd(2) 、 signalfd(2) ......),也许使用pipe(7 ) 进行通信)或unix(7)套接字。 另见socket(7) 。
您可以启动线程分离,而不用担心加入。
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);
}
#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.