我今天一直在“玩”提升线程作为一个学习练习,我有一个很好的例子,我在几个月前建立(在我被打断之前,不得不放弃多线程一段时间)那表现出异常的行为。
当我最初编写它时,我使用的是MingW gcc 3.4.5,它有效。现在我正在使用4.4.0并且它没有 - 顺便说一句,我再次尝试使用3.4.5(当我安装4.4.0时,我将该版本保存为单独的文件夹)并且它仍在工作。
代码在问题的最后; 总结它的作用是在两个子线程中启动两个Counter
个对象(这些对象只是增加一个变量然后稍微睡一会儿,无限重复 - 它们算在内),主线程通过cin.get()
等待用户,然后中断两个线程,等待它们加入,然后输出两个计数器的结果。
符合3.4.5,按预期运行。
符合4.4.0它一直运行直到用户输入,然后死掉了如下所示的消息 - 似乎中断异常正在杀死整个过程?
在抛出''实例后终止调用' 此应用程序已请求Runtime以不寻常的方式终止它。 有关更多信息,请联系应用程序的支持团队。 抛出boost :: thread_interrupted'
此应用程序已请求Runtime以不寻常的方式终止它。 请联系应用程序的支持团队以获取更多信息。
从我读到的内容来看,我认为允许传播出子线程的任何(?)未捕获的异常会终止进程?但是,我在这里抓住中断,不是吗?使用3.4.5时至少我似乎。
那么,首先,我了解中断的工作原理吗? 并且,有关正在发生的事情以及如何解决的任何建议?
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/date_time.hpp>
//fixes a linker error for boost threads in 4.4.0 (not needed for 3.4.5)
//found via Google, so not sure on validity - but does fix the link error.
extern "C" void tss_cleanup_implemented() { }
class CCounter
{
private:
int& numberRef;
int step;
public:
CCounter(int& number,int setStep) : numberRef(number) ,step(setStep) { }
void operator()()
{
try
{
while( true )
{
boost::posix_time::milliseconds pauseTime(50);
numberRef += step;
boost::this_thread::sleep(pauseTime);
}
}
catch( boost::thread_interrupted const& e )
{
return;
}
}
};
int main( int argc , char *argv[] )
{
try
{
std::cout << "Starting counters in secondary threads.\n";
int number0 = 0,
number1 = 0;
CCounter counter0(number0,1);
CCounter counter1(number1,-1);
boost::thread threadObj0(counter0);
boost::thread threadObj1(counter1);
std::cout << "Press enter to stop the counters:\n";
std::cin.get();
threadObj0.interrupt();
threadObj1.interrupt();
threadObj0.join();
threadObj1.join();
std::cout << "Counter stopped. Values:\n"
<< number0 << '\n'
<< number1 << '\n';
}
catch( boost::thread_interrupted& e )
{
std::cout << "\nThread Interrupted Exception caught.\n";
}
catch( std::exception& e )
{
std::cout << "\nstd::exception thrown.\n";
}
catch(...)
{
std::cout << "\nUnexpected exception thrown.\n"
}
return EXIT_SUCCESS;
}
答案 0 :(得分:0)
解决。
事实证明,添加编译器标志-static-libgcc
可以解决4.4.0的问题(并且对3.4.5没有明显的影响) - 或者至少在这种情况下程序会返回预期的结果。