struct Foo
{
boost::thread thread_;
void launchThread()
{
boost::thread(boost::bind(&Foo::worker, this));
}
void worker()
{
~Foo();
}
~Foo()
{
if (boost::this_thread::get_id() != thread_.get_id())
thread_.join();
}
};
В С++ 11 является ли законным в объединенном потоке для вызова деструктора класса, объявляющего поток?
EDIT1, более реалистичный пример:
struct Holder
{
std::unique_ptr<SocketClient> client_;
void ondisconnected(){client_.release();}
Holder()
{
//create SocketClient and launch the thread
}
}
struct SocketClient
{
boost::thread thread_;
void launchThread()
{
boost::thread(boost::bind(&SocketClient ::worker, this));
}
void worker()
{
run_ = true;
while (run_)
{
boost::system::error_code error;
auto receveidBytesCount = socket_.read_some(boost::asio::buffer(socketBuffer_), error);
if (error == boost::asio::error::eof)
{
disconnected_() // call Holder slot
return;
}
}
}
~SocketClient ()
{
run_ = false;
socket_.shutdown(boost::asio::socket_base::shutdown_both);
socket_.close();
if (boost::this_thread::get_id() == thread_.get_id())
thread_.detach();
else
thread_.join();
}
};
Нет. Присоединяемый поток должен быть соединен или отсоединен до уничтожения объекта thread
. Это не будет выполняться ни при вызове из этого потока. Деструктор потока вызывает terminate()
, заканчивая программу.
Разрешено ли отсоединять поток, зависит от того, уничтожаете ли вы объекты, к которым обращается поток. Это скорее зависит от крупномасштабного дизайна ваших взаимодействий потоков, и на самом деле нельзя ответить в целом.
Обратите внимание, что явно вызов деструктора, подобного этому, почти наверняка недействителен; Я предполагаю, что просто для иллюстрации того, что деструктор вызывается (более подходящим образом) в потоке.
std::thread
не уничтожает объект функции потока и любые параметры, которые вы указали в конструкторе std::thread
. Они не сохраняются как члены данных объекта std::thread
и уничтожаются при выходе из потока выполнения. Такое поведение стандартно.