#c #boost-thread
#c #boost-поток
Вопрос:
Я озадачен тем, почему эта программа выходит из строя. Это вся программа
#include<fstream>
#include<string>
#include<iostream>
#include <exception>
#include <boost/thread/thread.hpp>
void func( const std::stringamp; 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(amp;func, filename ));
thrd.join();
// func( filename ); // calling this does not cause a crash
}
catch( const std::exceptionamp; ex)
{
std::cout << ex.what() << std::endl;
}
return 0;
}
Окружающая среда
Windows 7
Visual Studio Express 2008
boost: пробовал как 1.44.0, так и 1.46.1
Связывание (пробовалось как динамическое, так и статическое)
Ответ №1:
Основная проблема заключается в том, что в текущем стандарте отсутствует поддержка переноса исключений из одного потока в другой. Когда исключение остается неперехваченным во вновь созданном потоке, оно достигает вершины стека и завершает работу программы, как если бы исключение было оставлено неперехваченным в main
. Учтите, что try
вход main
находится в стеке основного потока, но исключение находится в совершенно другом стеке.
Это задокументировано в boost thread: http://www.boost.org/doc/libs/1_46_1/doc/html/thread/thread_management.html#thread.thread_management.thread
В готовящемся стандарте есть поддержка перемещения исключений из одного потока в другой, но вам придется либо перехватывать и перемещать вручную, либо использовать конструкции более высокого уровня, такие как std::future
.
Ответ №2:
Вы создаете исключение в потоке, и нет окружающего блока catch для перехвата исключения. Обработчик находится примерно в том месте, где вы создаете поток, но поток выполняется в своем собственном отдельном контексте.
Если вы хотите перехватить исключение, генерируемое в потоке, вам нужно сделать это внутри этого потока.
Ответ №3:
Ускорение.Исключение имеет способ передачи исключений между потоками, описанный в http://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_exception_ptr.html
Это также часть предстоящего стандарта C 0X.