第一次在這裏發佈,但我已經徹底搜索這個問題的解決方案並且沒有解決方案。我有一個類,基本上使用一個靜態範圍的線程池來計算矩陣的條目。當需要進行新的計算時,靜態條件變量表示這一點。當程序結束時,一個靜態布爾標誌被改變,主線程在退出之前調用join_all。問題是,當我從int main()返回時,程序看起來在銷燬靜態變量期間掛起。C++/boost :: thread程序在join_all後掛起並從主返回
下面是執行計算的類粗糙源碼:
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);
}
}
這裏是主要方法的一些粗糙代碼。它實際上是由主調用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庫變量最終被銷燬時,問題就會發生。任何人都可以看到問題嗎?
你可以附加一個調試器並在程序低於'main()'時獲得堆棧跟蹤嗎? –
除去所有靜態信息,以便您有機會看到發生錯誤的位置? –
您的程序在Boost主幹上運行良好。 –