I am writing GUI application which use my own library which is based on boost::asio
an C++11 standard library. This is implementation of gui_client::OnInit
and gui_client::OnExit
methods of class gui_client
which derives from wxApp
:
bool gui_client::OnInit()
{
io_service_ = new boost::asio::io_service;
client_ = new client(*io_service_);
frame = new main_frame();
std::thread reader([this]() {
// thread code
});
reader_thread = &reader;
frame->Show();
Debug("Returning OnInit");
return true;
}
int gui_client::OnExit()
{
reader_thread->join();
return 0;
}
Everything compiles and application starts. I see debug information in command line ('Returning OnInit') and then:
terminate called without an active exception
I tried to set breakpoints in gdb
on some wxApp
functions, but I cannot find the place where error is returned. gui_client
class has only three methods:
virtual bool OnInit()
virtual int OnExit()
client * get_client()
When I do not start reader thread (std::thread reader
) everything works well. When I started thread with empty loop in lambda function I got error which I mentioned above. I'm also sure that thread code is correct because the same code works well in CLI testing application.
I use wxWidgets 3.0.1.0
and g++ 4.7.2
(Debian). I use this g++ command for comilation:
g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g -c -o [obj_file] [source]
and this command for linking:
g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g [obj_files] -ltamandua `wx-config --version=3.0 --libs` -lboost_system -pthread -o [output]
Problem is here:
std::thread reader([this]() {
// thread code
});
reader_thread = &reader;
reader
will be destroyed after OnInit
function ends (and terminate will be called, since thread
is joinable). You should use smart-pointer in class in this case, or create reader_thread
using new
, or simply save thread in object and assign it to your reader_thread
(reader_thread should be object, not pointer) via move.
1) reader_thread = std::make_shared<std::thread>([this]() {});
2) reader_thread = new std::thread([this]() {});
3)
std::thread reader([this](){});
reader_thread = std::move(reader);