2017-04-16 4 views
0

私はループを持っていますが、pthread_joinを呼び出しますが、ループの順序はスレッドの終了の順序と一致しません。 どうすればスレッドの完了を監視してから、参加を呼び出すことができますか?どのスレッドが完了したかを調べる方法

for (int th=0; th<sections; th++) 
{ 
    cout<<"start joining "<<th<<endl<<flush; 
    result_code = pthread_join(threads[th] , (void**)&status); 
    cout<<th<<" join error "<<strerror(result_code)<<endl<<flush; 
    cout<<"Join status is "<<status<<endl<<flush; 
} 

これは最初の 完了のスレッドにサービスを提供することにより、マルチスレッドのスループットを最大化するようで、私のソリューションです。この解決策は、pthread_joinループの順序に依存しません。私が参加を呼び出し、スレッドの完了を監視することができますどのように

// loop & wait for the first done thread 

    std::bitset<Nsections> ready; 
    std::bitset<Nsections> done; 
    ready.reset(); 
    for (unsigned b=0; b<sections; b++) ready.flip(b); 
    done = ready; 

    unsigned currIdx = 1;  
    int th = 0; 
    int th_= 0; 
    int stat; 

    while (done.any()) 
    { 

     // main loops waiting for 1st thread to complete. 
     // completion is checked by global vector 
     // vStatus (singlton write protected) 
     // and not by pthread_exit returned value, 
     // in ordder to maximize throughput by 
     // post processig the first 
     // finished thread. 

     if ((obj.vStatus).empty()) { Sleep (5); continue; } 

     while (ready.any()) 
     { 
      if (sections == 1) break; 

      if (!(obj.vStatus).empty()) 
      { 
       if (currIdx <= (obj.vStatus).size()) 
       { 
        th_ = currIdx-1; 

        std::string s = 
        ready.to_string<char,std::string::traits_type,std::string::allocator_type>(); 
        cout<<"checking "<<th_<<"\t"<<s<<"\t" 
         <<(ready.test(th_)?"T":"F")<<"\t"<<(obj.vStatus)[th_].retVal <<endl;   

        if ((obj.vStatus)[th_].retVal < 1) 
        { 
         if (ready.test(th_)) 
          { 
          th=th_; 
          ready.reset(th); 
          goto retry; 
         } 
        } 
       } 
      } 
      Sleep (2); 

     } // while ready 


     retry: 
     cout<<"start joining "<<th<<endl<<flush; 
     result_code = pthread_join(threads[th] , (void**)&status); 

     switch (result_code) 
     { 
      case EDEADLK: goto retry; break; 
      case EINVAL: 
      case ESRCH: 
      case 0: 
         currIdx++; 
         stat = status->retVal; 
         free (status); 
         done.reset(th); 

         std::string s = 
        done.to_string<char,std::string::traits_type,std::string::allocator_type>(); 
        cout<<"joined thread "<<th<<"\t"<<s<<"\t" 
         <<(done.test(th)?"T":"F")<<"\t"<<stat <<endl; 

         while (true) 
         { 
         auto ret=pthread_cancel (threads[th]) ; 
         if (ret == ESRCH) { netTH--; break; } 
         Sleep (20); 
         } 
         break; 
     } 
+0

これにより、いくつかのフラグを確認する必要が生じる場合があります。 'std :: async'や' std :: future'を生成する他のメカニズムなど、抽象度の高いレベルを使用してみませんか?スレッドが完了したらboolを設定すると、http://stackoverflow.com/questions/10890242/get-the-status-of-a-stdfuture – WhiZTiM

+0

を参照してください。メインスレッドのループでboolをチェックしてください – DanielCollier

+0

ダニエルありがとうございますが、pthread_createのargであるbool varは終了前に更新されていないと思います – BNR

答えて

0

完了を検出することにより、結合を検出します。 (つまり何も特別なことはありません)

私はpthread_joinを呼び出すループを持っていますが、ループの順序はスレッドの終了の順序と一致しません。

ループの順序は関係ありません。

a)thread[main] を呼び出すと、終了するのはthread[1]までです。その後、スレッド[main]は残りのループを続行することが許可されます。

b)thread[1]の前にthread[2]が終了すると、thread[main]thread[2].joinを呼び出すだけですぐに戻ります。再び、thread[main]が続きます。

c)が(ループシーケンスに一致する)thread[2]より前に終了するようにする努力は、驚くほど時間がかかる作業であり、利点はありません。

更新が進行中...コードを検索していますが、すでに提出していると思います。

+0

"ループの順序は関係ありません" - プログラムの要件によって異なります。たとえば、ジョインを実行するスレッドは、完了したスレッドの処理を収集し、それが完了したときに処理する(たとえば、中間結果をユーザーに表示するなど)場合があります。 –

関連する問題