2017-04-16 228 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

“循环顺序无关紧要” - 这取决于程序的要求。例如,执行连接的线程可能希望收集已完成线程的工作,并在完成时处理它(例如,向用户显示中间结果),而不是阻塞某些可能无法完成的任意线程。 –

相关问题