When the destructor for std::thread
is invoked, a call to either join()
or detach()
must have been made. If a thread has not been joined or detached, then by default std::terminate
will be called. Using RAII, this is generally simple enough to accomplish:
class thread_joiner
{
public:
thread_joiner(std::thread t)
: t_(std::move(t))
{ }
~thread_joiner()
{
if(t_.joinable()) {
t_.join();
}
}
private:
std::thread t_;
}
This is then used like so:
void perform_work()
{
// Perform some work
}
void t()
{
thread_joiner j{std::thread(perform_work)};
// Do some other calculations while thread is running
} // Thread is automatically joined here
This also provides exception safety; if we had created our thread normally and the work done in t()
performing other calculations had thrown an exception, join()
would never have been called on our thread and our process would have been terminated.