программа boost :: thread аварийно завершает работу при выдаче исключения std :: - PullRequest
5 голосов
/ 22 мая 2011

Я озадачен, почему эта программа падает. Это вся программа

#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 ]

5 голосов
/ 22 мая 2011

Основная проблема в том, что в текущем стандарте нет поддержки перемещения исключений из одного потока в другой. Когда исключение остается необработанным во вновь созданном потоке, оно достигает вершины стека и завершает программу, как если бы исключение было оставлено необработанным в main. Учтите, что try в main находится в стеке основного потока, но исключение находится в совершенно другом стеке.

Это задокументировано в буст-ветке: http://www.boost.org/doc/libs/1_46_1/doc/html/thread/thread_management.html#thread.thread_management.thread

В будущем стандарте есть поддержка перемещения исключений из одного потока в другой, но вам придется либо ловить и перемещать вручную, либо использовать конструкции более высокого уровня, такие как std::future.

2 голосов
/ 22 мая 2011

Вы генерируете исключение в потоке, и нет окружающего блока catch, чтобы перехватить исключение.Обработчик находится вокруг того места, где вы создаете поток, но поток работает в своем отдельном контексте.

Если вы хотите перехватить исключение, выброшенное в потоке, вам нужно сделатьтак что внутри этой темы.

1 голос
/ 22 мая 2011

Boost.Exception имеет способ транспортировки исключений между потоками, описанный в http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html

Это также часть будущего стандарта C ++ 0X.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...