41

メインスレッドで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番目のスレッドが作成されないことです。これは私が望むものではありません。

私が欲しいのは、2つのスレッドがメインスレッドですぐに作成され、メインスレッドがそれらが終了するのを待つことです。pthread_joinトリックができないようですよね?

多分semaphore私は仕事をすることができると思いましたが、他の方法はありますか?

4

4 に答える 4

74
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;
}
于 2012-07-24T05:17:57.363 に答える
17

最初にすべてのスレッドを作成し、次にそれらすべてを結合します。

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)の2番目の引数に渡します。これらは、切り離された状態でスレッドを作成します。または、 Jxhの回答pthread_detachで説明されているように使用します。

いくつかの優れたPthreadチュートリアルを読むことを忘れないでください。ミューテックスと条件変数を使用することをお勧めします。

QtPOCO (C ++の場合)など、それらをラップするフレームワークを使用するか、優れたC++の本を読んでC++スレッドを使用することができます。

概念的には、スレッドにはそれぞれの呼び出しスタックがあり、継続に関連しています。彼らは「重い」です。

エージェント指向のプログラミングアプローチを検討してください。原則として、多くのスレッドは必要ありません(たとえば、10コアプロセッサで20スレッドが妥当であり、多くのスレッドがスリープしていない限り、200スレッドは適切ではありません)。または待機中)そして、スレッドがミューテックス変数と条件変数を使用して同期し、他のスレッドと非常に頻繁に(1秒あたり数回)通信および/または同期することを望んでいます。スレッド間の通信の別の方法として、 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)も参照してください。

スレッド間の通信プロトコルを(紙に)文書化することを忘れないでください。理論的なアプローチについては、 π計算に関する本を読み、ライスの定理に注意してください。並行プログラムのデバッグは困難です。

于 2012-07-24T05:20:02.877 に答える
4

スレッドを切り離して開始することができ、結合について心配する必要はありません。

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);
}
于 2012-07-24T06:54:26.097 に答える
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
}
于 2020-10-16T17:05:01.537 に答える