N2184 Thread Launching for C++0X

The design of this thread is an evolution from boost::thread. The intent is to reuse as much of the boost::thread experience as possible, keeping the good, and changing the very minimum necessary to respond to the known limitations of this field experience.

  • This proposal adds cancellation to the boost::thread, which is a significant complication. This change has a large impact not only on thread but the rest of the C++ threading library as well. It is believed this large change is justifiable because of the benefit.
    • The thread destructor must now call cancel prior to detaching to avoid accidently leaking child threads when parent threads are canceled.
    • An explicit detach member is now required to enable detaching without canceling.

N2320 Multi-threading Library for Standard C++

A significant complicating factor is the introduction of cancellation, and the de-facto differences between thread cancellation in C today, and the thread cancellation proposed for C++ in N2184.

N2447 Multi-threading Library for Standard C++

This is a revision of N2320 which removes cancellation/interruption and changes condition variables per the suggestions in N2406. This is the course of a action requested by the combined LWG/Concurrency working groups at the Kona meeting.

N2497 Multi-threading Library for Standard C++ (Revision 1)

If joinable() then detach(), otherwise no effects. [Note: Destroying a joinable thread can be unsafe if the thread accesses objects or the standard library unless the thread performs explicit synchronization to ensure that it does not access the objects or the standard library past their respective lifetimes. Terminating the process with _exit or quick_exit removes some of these obligations. -- end note]

N2802: A plea to reconsider detach-on-destruction for thread objects

Given the absence of a cancellation facility, acceptable options include:

  • Joining the thread. This has the unfortunate consequence that throwing an exception will wait for threads being destroyed. But this is much more benign than stack overwrite errors by another thread. And if it results in serious responsiveness issues, e.g. because it creates deadlocks, it is debuggable. It does not risk security holes.
  • Any specification that allows or requires the implementation to treat destruction of a joinable thread as an error. Lawrence Crowl suggested simply replacing the detach() call in the current specification with a call to terminate() by analogy with unhandled exceptions. This is another error condition that cannot be safely reported via an exception.

N2802 (Alternative 2) adopted to C++11

N3630 async, ~future, and ~thread (Revision 1)

For similar reasons to the notes above, we are in the peculiar situation where ~thread calls terminate if not joined. That too is a problem, as noted for example in [2]
Instead, exactly one of the following should be true:

  • (preferred) either thread owns the resource as an RAII type and therefore ~thread should join
  • or it is not and ~thread should do nothing.

We propose the former as this is consistent with the rest of the intent of the thread type, such as

N3636 ~thread Should Join

SG1 discussion of N3630 resulted in direction in favor of the proposal that ~thread calls join, not
terminate, if the thread was not already joined.
This has no effect on programs that do not currently terminate. It just replaces the requirement to call terminate with the requirement to instead call join.

Proposed Wording
If joinable(), calls join(). Otherwise, has no effects. [Note: Because ~thread is required to be
noexcept (, if join() throws then std::terminate() will be called. -- end note]

P020R60 Discussion about std::thread and RAII

C++ continues not to provide a thread type that would join() automatically on scope exit. This causes exception-safety problems, because failing to join() in all code paths causes the destructor of a std::thread to terminate().

  • Solution 1: Change std::thread::~thread to auto-join
  • Solution 2: Add a new thread type that auto-joins
  • Solution 3: Add a thread wrapper that auto-joins

P0206R1 A joining thread

Solution 2: Add a new thread type that auto-joins
In a large-group discussion in Jacksonville, the outcome was that a new thread type that joins in its destructor should be added. The benefit of this solution is that it's non-intrusive; all existing users of std::thread are unaffected, for better or worse. Replacing the uses of std::thread with the uses of the new type where need be is arguably straightforward.

P0660R0 A Cooperatively Interruptible Joining Thread

In Jacksonville 2016 we had an evening session P0206R0 with the following outcome:
Unfortunately, this decision was reverted later in Oulu in a smaller group so that we didn’t get what the majority voted for.
In addition, there are constantly requests to support interruption for started threads, which is implemented in Boost.Thread and was discussed but rejected during the standardization of std::thread for C++11.
It’s time now to fulfill the need of an easy to use basic thread class for application programmers based on the experience of the existing Boost thread classes. Not providing this currently hinders projects to switch from Boost to the C++ standard library.

P0660R10 Stop Token and Joining Thread, Rev 10

This is the proposed wording for a cooperatively interruptible joining thread.

→ Adopted 2019-07 to C++20