2017-05-09 4 views
0

NUM_TREADSスレッドがあり、job2()を実行する前にjob1()を完了しなければならないとします。このように、これが起こることを保証する方法:すべてのスレッドが1つのジョブを終了してから別のジョブを終了するまで待ちます

void thread_func(void *arg) 
{ 
    while(1) { 
     job1(); 
     some_kind_of_waiting(); 
     job2(); 
    } 
    return NULL; 
} 

が作業を以下またはその他の/より良い解決策があるようなセマフォウィル?

{ 
    static int done; 
    static sem_t semaphore; 

    if(__sync_fetch_and_add(&done, 1) == THREAD_NUMS-1) { 
     done = 0; 
     for(i = 0; i < THREAD_NUMS-1; i++) 
      sem_post(&semaphore); 
    } else 
     sem_wait(&semaphore); 
} 

ありがとう。

+2

これはcまたはC++の質問ですか?答えは、使用している言語によって異なります。 –

+3

'void'関数から' NULL'を返しています。 –

+0

C++ std :: futureを使用できますか? – Alek86

答えて

3

これは、pthreadsの障壁が解決しようとしている問題です。

pthread_barrier_t barrier; 

pthread_barrier_init(&barrier, NULL, NUM_THREADS); 

と同期するためにpthread_barrier_wait()を使用します:(あなたのメイン機能では、以前のスレッドを生成する)NUM_THREADSとのバリアを初期化

void *thread_func(void *arg) 
{ 
    while(1) { 
     job1(); 
     pthread_barrier_wait(&barrier); 
     job2(); 
    } 
    return NULL; 
} 

あなたはまた、他のすべてのスレッドまで待機するスレッドが必要な場合再びjob1()に開始することができ、それらのいずれかの前job2()をcompeltedしている、あなたは、バリアの2番目のウェイトを追加することができます。

void *thread_func(void *arg) 
{ 
    while(1) { 
     job1(); 
     pthread_barrier_wait(&barrier); 
     job2(); 
     pthread_barrier_wait(&barrier); 
    } 
    return NULL; 
} 
+0

後続のループのバリアをどのように再初期化しますか? 'job2()'が完了した後、 'job1()'を再開する前にスレッドを待たせるために、第2の障壁が必要ですか?または最初の障壁を再初期化することができますか? –

+0

@JonathanLeffler:バリアを再初期化する必要はありません。スレッドがバリアから解放された直後に、スレッドが再び待機するためのバリアが利用可能になります。 – caf

+0

情報ありがとうございます。 –

1

通常、名前がbarrierである高水準並行制御構造を記述します。 C++標準ライブラリはproposedでしたが、将来はC++標準ライブラリの一部になりますが、バリアの実装はありません。

標準ライブラリが解決策を提供するまでは、もちろんバリアを実装することもできます(条件変数を使用できます)。platform specific threading APIまたはwrapper libraryを使用します。

関連する問題