BOOST::thread what problems are there in deleting a joinable thread?

boost, c++, multithreading

Solution

It depends. Originally Boost's implementation would detach an unjoined thread upon destruction. This has been changed since version 1.52 to match the behavior of C++11's `std::thread`: Destroying an unjoined thread now invokes `std::terminate` (which will crash the program by default). The old behavior will remain available as a deprecated feature until 1.56 and can be activated by setting the `BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE` preprocessor flag.

For your example of a thread that is stuck in an a blocking call the advice must therefore be: Don't do it. Only use blocking I/O calls that allow specifying a timeout or use asynchronous I/O instead. You need to be able to signal a thread waiting for I/O that it should terminate, otherwise you risk a deadlock when shutting down your program.

Theoretically you could just not join the thread (ie. either detach or leak the `boost::thread` object). However this usually causes lots of other headaches, as you cannot guarantee that resources held by that thread will be cleaned up appropriately. This makes it very hard to reason about the behavior of such a thread. Mind that ISO-C++ did decide to invoke `terminate` here for a reason.

Problem

What are the problems one could encounter from destroying a joinable thread pointer? (i.e. calling `delete thread`) The boost reference is a bit fuzzy, more exact answers are desirable. Here's a specific example: Assume a child thread is stuck on a non-interruptable system call such as `read(0)` with no one manning the keyboard. Thus, calling `thread->interrupt()` followed by a `thread->try_join_for()` will leave the thread joinable. What should be done? From the the reference guide, it seems that one must either detach the thread or leak the thread pointer. What actually happens when a stuck thread is detached or pointer leaked are outside of the scope of this question. Background: In the `boost::thread::~thread()` reference is the following verbiage. Being the "she sells seashells by the seashore" of the BOOST reference guide, it requires reading three or four times before one can parse it; Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. The short of this (from what I can tell) is (that) it (is) a (bad) idea (to) destroy (a) boost::(thread) pointer (while) it (is) still (joinable). And who's raising the exception mentioned? The child thread? The destructor?

Original source