boost :: thread程序在抛出std :: exception时崩溃

时间:2011-05-22 10:05:47

标签: c++ boost-thread

我很困惑为什么这个程序崩溃了。这是整个计划

#include<fstream>
#include<string>
#include<iostream>
#include <exception>
#include <boost/thread/thread.hpp>

    void func( const std::string& filename )
    {
        std::ofstream outFile( filename.c_str(), std::ios::binary);
        if( !outFile.is_open() )
        {
            std::string err("Could not open file ");
            err.append(filename);
            err.append(" for writing");
            throw std::exception(err.c_str());
        }
    }

    int main()
    {
        std::string filename("xX:\\does_not_exist.txt");
        try
        {
            boost::thread thrd(boost::bind(&func, filename ));
            thrd.join();
        //  func( filename ); // calling this does not cause a crash
        }
        catch( const std::exception& ex)
        {
            std::cout << ex.what() << std::endl;
        }
        return 0;
    }

环境
Windows 7
Visual Studio Express 2008
提升:尝试1.44.0和1.46.1
链接(尝试动态和静态)

3 个答案:

答案 0 :(得分:5)

基本问题是,在当前标准中,不支持将异常从一个线程移动到另一个线程。当新创建的线程中的异常未被捕获时,它将到达堆栈的顶部并完成程序,就像在main中未被捕获的异常一样。考虑try中的main位于主线程的堆栈中,但异常位于完全不同的堆栈中。

在boost线程中记录了这一点:http://www.boost.org/doc/libs/1_46_1/doc/html/thread/thread_management.html#thread.thread_management.thread

在即将推出的标准中,支持将异常从一个线程移动到另一个线程,但您必须手动捕获和移动或使用更高级别的构造,如std::future

答案 1 :(得分:2)

您在线程中抛出异常,并且没有周围的catch块来捕获异常。处理程序位于创建线程的位置,但线程在其自己的单独上下文中运行。

如果你想捕获线程中抛出的异常,那么你需要在该线程中执行此操作。

答案 2 :(得分:1)

Boost.Exception有一种在http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html

中描述的线程之间传输异常的方法

这也是即将推出的C ++ 0X标准的一部分。