2017-01-02 193 views
2

我創建了一個線程池以在4個線程之間分配100個計算。線程池stucks

我不明白爲什麼下面的代碼在4次計算後出現問題。每次計算後,線程必須被釋放,我期望.joinable()返回false,以便程序繼續。

結果:

[[[01] calculated 
] calculated 
2] calculated 
[3] calculated 

代碼:

#include <string> 
#include <iostream> 
#include <vector> 
#include <thread> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread/thread.hpp> 
#include <cmath> 

class AClass 
{ 
public: 

    void calculation_single(std::vector<double> *s,int index) 
    { 
     (*s)[index]=sin(double(index)); 
     std::cout<<"["<<index<<"] calculated \n"; 
    } 

    void calculation() 
    { 
     const uint N_nums=100; 
     const uint N_threads=4; 
     std::vector<double> A; 
     A.assign(N_nums,0.0); 
     std::vector<std::thread> thread_pool; 
     for(uint i=0;i<N_threads;i++) 
      thread_pool.push_back(std::thread()); 

     uint A_index=0; 
     while(A_index<N_nums) 
     { 
      int free_thread=-1; 
      for(uint i=0;i<N_threads && free_thread<0;i++) 
       if(!thread_pool[i].joinable()) 
        free_thread=i; 
      if(free_thread>-1) 
      { 
       thread_pool[free_thread]= 
        std::thread(
         &AClass::calculation_single, 
         this, 
         &A, 
         int(A_index)); 
       A_index++; 
      } 
      else 
      { 
       boost::this_thread::sleep(boost::posix_time::milliseconds(1)); 
      } 

     } 

     // wait for tasks to finish 
     for(std::thread& th : thread_pool) 
      th.join(); 
    } 

}; 

int main() 
{ 
    AClass obj; 
    obj.calculation(); 
    return 0; 
} 

回答

2

線程是可連接的,如果它不是空的基本。

完成任務的線程不爲空​​。

std::thread bob; 

bob不可連接。

您的線程是。你沒有做任何事使他們無法加入。

此外,繁忙的等待是一個糟糕的線程池。

創建消費者生產者隊列,消耗任務和中止方法的線程池。通過打包任務將任務送入隊列並返回std::future<T>。不要爲每個任務產生一個新的線程。

+0

我該如何解決這個問題?什麼來代替'joinable'? – ar2015

+0

@ ar2015 - 您需要讓每個線程通過設置每線程互斥鎖保護標誌並指示條件變量來指示它已完成其任務。當主循環看到所有線程都可以連接時,它會獲取互斥鎖,並等待條件變量,直到至少有一個完成標記被設置,然後再加入相應的線程。這也將擺脫愚蠢的忙碌等待投票。 –

+0

爲什麼*忙等待*是一個壞主意? – ar2015