第一次在这里发帖,但我已经彻底寻找这个问题的解决方案并且没有解决方案。我有一个类,它基本上使用静态范围的线程池来计算矩阵的条目。当需要进行新的计算时,静态条件变量会发出信号。当程序结束时,一个静态布尔标志被改变,主线程在退出前调用join_all。问题是当我从 int main() 返回时,程序在静态变量的销毁过程中似乎挂起。
这是执行计算的类的粗略源代码:
class FunctionCalculator
{
public:
static void createWorkers();
static void destroyWorkers();
static void calcFunction();
private:
static void run();
static boost::thread_group workers_;
static boost::mutex theLock_;
static int curIndex_;
static unsigned int numCalcsComplete_;
static boost::condition_variable stateChange_;
static boost::condition_variable calculationFinished_;
static bool finished_;
static struct SharedCalcData { // some vars } calcData_;
};
// static member definitions
int FunctionCalculator::curIndex_;
unsigned int FunctionCalculator::numCalcsComplete_;
boost::mutex FunctionCalculator::theLock_;
boost::condition_variable FunctionCalculator::stateChange_;
boost::condition_variable FunctionCalculator::calculationFinished_;
boost::thread_group FunctionCalculator::workers_;
bool FunctionCalculator::finished_;
FunctionCalculator::SharedCalcData FunctionCalculator::calcData_;
void FunctionCalculator::createWorkers()
{
finished_ = false;
curIndex_ = -1;
for( unsigned int i = 0; i < 4; i++ )
workers_.create_thread( boost::bind( &FunctionCalculator::run ) );
}
void FunctionCalculator::destroyWorkers()
{
{
boost::mutex::scoped_lock lock( theLock_ );
finished_ = true;
curIndex_ = 0;
stateChange_.notify_all();
}
workers_.join_all();
}
void FunctionCalculator::run()
{
unsigned int i = 0; // the column of the matrix to fill in
while ( true )
{
{
boost::mutex::scoped_lock lock( theLock_ );
// block if the calculation is finished until there's a new calculation
while ( curIndex_ < 0 )
stateChange_.wait( lock );
// check if it's time for threads to die
if ( finished_ )
break;
// get the next index to process
i = (unsigned int)curIndex_++;
// signal all threads to block if this is the last thread in the calculation
if ( i == 49 )
curIndex_ = -1;
}
// perform calculation/fill in matrix
{
boost::mutex::scoped_lock lock( theLock_ );
++numCalcsComplete_;
// wake up the main thread if this was the last thread in the calculation
if ( numCalcsComplete_ == 50 )
calculationFinished_.notify_one();
}
}
}
void FunctionCalculator::calcFunction()
{
// assign calcData_
{
boost::mutex::scoped_lock lock( theLock_ );
curIndex_ = 0;
numCalcsComplete_ = 0;
stateChange_.notify_all();
while ( curIndex_ >= 0 )
calculationFinished_.wait( lock );
}
}
这是主要方法的一些粗略代码。它实际上是由 main 创建的一个对象,它调用 createWorkers() 和 calcFunction() 实际上由 Gnu 科学库调用(为此我使用静态成员),但想法是这样的:
int main( int argc, char* argv[] )
{
FunctionCalculator fc;
FunctionCalculator::createWorkers();
for ( int i = 0; i < 10; i++ )
fc.calcFunction();
FunctionCalculator::destroyWorkers();
return EXIT_SUCCESS;
}
调用 EXIT_SUCCESS 后,程序挂起,但我已验证 FunctionCalculator 中的四个线程在调用 destroyWorkers() 后已完成 run() 方法。由于程序从main返回,我的理论是问题发生在静态boost库变量最后被销毁时。任何人都可以看到问题吗?