
Howard Hinnant wrote:
I believe one of the big differences is : How soon after join() can the thread clean up resources?
It depends on what do you mean by resources and how do you interpret the POSIX specification. I believe that a thread is allowed to clean up everything immediately after it terminates except for the very minimum that is required to keep its pthread_t valid. That is, the thread stack and its thread-local storage are, I believe, not required to hand around after its termination, regardless of whether you call pthread_join or pthread_detach. I do know that POSIX specifically talks about resources in the description of pthread_detach, but my interpretation is that its only real effect on a quality implementation should be to invalidate the pthread_t. But if we conservatively accept that the underlying implementation doesn't reclaim resources until pthread_detach or pthread_join is called, this still doesn't mean that we necessarily have to do a pthread_detach before ~thread. Since - under the current N2184 semantics - an std::thread object is effectively an empty shell after join() or detach(), it doesn't burden the user much to move the invalidation to ~thread since it's one t = std::thread() assignment away. Even if we leave detach() with the current "leave a carcass behind" semantics (which also seems reasonable), ...
join() { // Don't want to pretend to join with non-existent // (or detached) thread, make noise if (handle_ == 0) throw ?; while (!tl->done) tl->cv1.wait(); detach(); // point of contention with N2178, makes join non-const, // and disables multi-join. Without it, resources not // released until explicit detach() or ~thread() }
... we can still remove this detach() call from join() and the user is free to get the old semantics back by just calling detach() explicitly after join() (whereas the reverse is not true).