2017-04-16 61 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'的機制?請參見http://stackoverflow.com/questions/10890242/get-the-status-of-a-stdfuture – WhiZTiM

+0

當線程完成時設置一個布爾值。在主線程中檢查一個循環中的bool – DanielCollier

+0

感謝Daniel,但我認爲pthread_create中的arg的bool var在終止前不會更新 – BNR

回答

0

如何監控線程完成,然後加入到通話?

通過讓連接檢測完成。 (即沒有什麼特別的)

我有一個循環調用pthread_join,但循環的順序不匹配線程終止的順序。

循環的順序並不重要。

a)thread[main]調用thread[1].'join'將被暫停,直到thread[1]退出。之後,線程[main]將被允許繼續循環的其餘部分。

b)當thread[2]thread[1]之前終止,thread[main]呼叫thread[2].join只是立即返回。再次,thread[main]繼續。

c)確保thread[1]thread[2]之前終止(以匹配循環序列)的努力是非常費時的努力,沒有益處。

正在進行更新...查找我認爲已經提交的代碼。

+0

「循環順序無關緊要」 - 這取決於程序的要求。例如,執行連接的線程可能希望收集已完成線程的工作,並在完成時處理它(例如,向用戶顯示中間結果),而不是阻塞某些可能無法完成的任意線程。 –