簡體   English   中英

如何讓主線程等待所有子線程完成?

[英]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 教程 您可能想要使用互斥量和條件變量。

您可以使用包裝它們的框架,例如QtPOCO (在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM