Search code examples
c++multithreadingc++11detach

Why can detached thread in C++11 execute even if the destructor has been called


I just read the doc about std::thread.detach() in C++11.

Here is my test:

#include <iostream>
#include <thread>
#include <chrono>

static int counter = 0;    

void func()
{
    while (true) {
        std::cout<<"running..."<<std::endl;
        std::cout<<counter++<<std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}


int main()
{
    {
        std::thread t(func);
        t.detach();
    } // t is released after this line
    // t has died, so who is holding the resources of the detached thread???

    std::cin.get();

    return 0;
}

This code works as expected. So it seems that the thread can keep running even if its destructor has been invoked. Is this true?

If it's true, who on earth holds the resources of the thread after the object t is released? Is there some mechanism to hold the resources, for example, a hidden anonymous object?


Solution

  • In C++, std::thread does not manage the thread of execution itself. C++ does not have controls for managing the thread of execution at all.

    std::thread manages the thread handle - the identifier of a thread (thread_t in Posix world, which was largely a model for std::thread). Such identifier is used to communicate (as in control) with the thread, but in C++, the only standard way of communication would be to join the thread (which is simply waiting for thread's completion) or detaching from it.

    When std::thread destructor is called, the thread handle is also destructed, and no further controlling of the thread is possible. But the thread of execution itself remains and continues being managed by implementation (or, more precisely, operation system).

    Please note, for non-detached threads std::threads destructors throws an exception if the thread has not been joined. This is simply a safeguard against developers accidentally loosing the thread handle when they didn't intend to.