Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使主线程等待所有子线程完成?_C_Multithreading - Fatal编程技术网

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

C 如何使主线程等待所有子线程完成?,c,multithreading,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)

我打算在主线程中触发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?
    }
}
void*例程(void*arg)
{
睡眠(3);
}
int main()
{
对于(int i=0;i<2;i++){
pthread_t tid;
pthread_创建(&tid,NULL,例程,NULL);
pthread_join(&tid,NULL);//此函数将阻止主线程,对吗?
}
}
在上面的代码中,
pthread\u join
确实让主线程等待子线程,但问题是,在第一个线程完成之前,不会创建第二个线程。这不是我想要的

我想要的是,两个线程立即在主线程中创建,然后主线程等待它们完成。似乎
pthread\u join
不能完成这个任务,是吗

我想,也许通过一个
信号灯
我可以完成这项工作,但还有其他方法吗?

intmain()
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]; 对于(int i=0;i<2;i++){ pthread_create(&tid[i],NULL,例程,NULL); } 对于(int i=0;i<2;i++) pthread_join(tid[i],NULL); 返回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_t tid[2];
///创建所有线程
对于(int i=0;i<2;i++){
pthread_create(&tid[i],NULL,例程,NULL);
}
///通过连接线程来等待所有线程
对于(int i=0;i<2;i++){
pthread_join(tid[i],NULL);
}
或者,使用一些
pthread\u attr\t
变量,然后 然后将其地址传递给第二个参数。Thos将以分离状态创建线程。或者使用
pthread\u detach
,如中所述

记得读一些好的。您可能希望使用互斥量和条件变量

您可以使用包装它们的框架,例如,或(在C++中),或者阅读一本好的手册并加以使用

从概念上讲,线程有各自的和相关的。它们很重


考虑一些方法:根据经验,您不希望有很多线程(例如,一个服务器上有20个线程是合理的,除非有很多线程处于睡眠或等待状态,否则200个线程是不合理的),并且确实希望线程使用互斥锁进行同步,并经常(每秒几次)与其他线程通信和/或同步。另请参见、、和,作为线程之间通信的另一种方式。避免与线程一起使用,并小心使用(可能仅在主线程中使用)。

您可以从分离的线程开始,而无需担心连接问题

for (int i = 0; i < 2; i++) {
    pthread_t tid;
    pthread_create(&tid, NULL, routine, NULL);
    pthread_detach(tid);
}
pthread_exit(0);
for(int i=0;i<2;i++){
pthread_t tid;
pthread_创建(&tid,NULL,例程,NULL);
pthread_detach(tid);
}
pthread_退出(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);
}
void*例程(void*arg)
{
int*fds=(int*)arg;
pthread_t t=pthread_self();
usleep((rand()/(1.0+rand_MAX))*1000000);
写入(fds[1],&t,sizeof(t));
}
int main()
{
int-fds[2];
srand(时间(0));
管道(fds);
对于(int i=0;i<2;i++){
pthread_t tid;
pthread_创建(&tid,NULL,例程,fds);
printf(“已创建:%llu\n”,(未签名长)tid);
}
对于(int i=0;i<2;i++){
pthread_t tid;
读取(fds[0],&tid,sizeof(tid));
printf(“加入:%llu\n”,(未签名长)tid);
pthread_join(tid,0);
}
pthread_退出(0);
}
#包括
#包括
int-icnt=0//在非bss数据段中
pthread_mutex_t lock//创建的锁变量存储在bss数据段中
void*线程计数(void*args)//同步
{
pthread_mutex_lock(&lock);//锁获取
icnt++;

对于(int x=1;x将线程存储在一个容器中,然后在创建完所有线程后对每个线程进行连接。如果其中一个线程在创建完所有线程之前完成,则效果不太好?我知道这已经很晚了,但您不必从管道关闭fds吗?@user1075375否。退出该进程就足够了。是的,但有人可能最终在一个容器中使用此示例代码工作线程退出时不立即退出的进程。哦,对他们来说太糟糕了,他们不知道如何释放他们的FD。@user1075375如果进程不退出,管道应该保持打开状态以供将来的线程使用。tbh,这有点像说主线程中的malloc不应该被释放,因为它可以被重用。如果以后生成的线程不能释放使用这些FD,在大多数系统上只会浪费比内存还少的资源。在windows上如何做到这一点?@perrealI知道这可以追溯到很久以前,但我想问一件事。当
pthread\u create
返回时,线程可能会正确启动,这会不会导致任何问题I线程在加入之前被创建和终止?I不完全理解您的担忧,但请阅读join函数的文档。如果线程正在执行或刚刚返回,它将等待线程。据我所知,此代码可能无法工作。函数将挂起“主线程”在线程A完成其执行之前,问题是线程B可能已经在这段时间内完成,因此对的下一次调用将生成未定义的行为。这里的连接调用来自单个线程,人们喜欢将其称为主线程。因此您的引用不适用。如果从多个线程调用pthread_join,则将是另一个st注意,生成的踏板都不会超出
例程
。主要问题是pthread_join()因此,如果有512个线程每+/-5小时运行10小时,线程1-511将在线程0完成之前不会连接。其中一个线程可能会提前很多时间结束。我不确定在许多情况下分离它们是否有用。如果时间或多或少是恒定的,我们可以以2分钟的延迟交错创建,例如。
#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
}