2017-01-02 154 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