Search code examples
c++11stdthread

When exactly is a destructor or terminate on a thread called


I am using C++11 std::thread. My confusion is based on the following:

terminate() on a thread is called if neither join() nor detach() is called on it. That means when a thread returns:

a. it checks whether a join() or detach() on it is called, if not, then terminate() is called(produces a coredump),

b. if join() is called the destructor of the thread would be called by main(or calling thread)

c. if a detach() was called while the thread was executing, the thread won't return to main for cleanup, instead this thread itself will be responsible for calling its own destructor

Question: If the above points were true then i dont understand at which exact point is the decision made wehter to terminate a thread or not based on whether a join() or detach() is called or not?

void function_1()
{
        return;
}
int main()
{
        std::thread t1(function_1);
        std::cout<<"\nFirst Sleep for 5 seconds:\n"; 
        sleep(5);

        cout<<"\n2nd Sleep for 5 seconds:\n";
        sleep(5);

        if(t1.joinable())
        {
                cout<<"\nGonna join()\n";
                t1.detach();
        }
        cout<<"Exiting from main ...\n";

}

Since the thread would finish its execution before 5th second, i assumed the thread should be terminated as there is no join()/detach() till this point. But there's no terminate() called. Instead a thread is detached succesfully.

However if i dont detach then terminate is called after 2 sleep after "Exiting from main....", right before return 0; Does that mean that the thread is not cleaned up(its destructor not called), until main thread(or called thread) returns?

Is that the reason why one should detach() so that the cleanup of the thread doesn't have to wait till main(or caller thread) returns?


Solution

  • Looks like you are confusing two things: the std::thread object, and the thread of execution that that object manages.

    The call to std::terminate is triggered by the destructor of the std::thread object if it is joinable. This is not directly related to whether or not the thread of execution managed by the std::thread object has finished executing.

    In your code, the destructor of t1 is what would trigger std::terminate. t1 is an ordinary C++ object, a local variable of main here. It gets destructed when its scope ends - end of main here. So you must have made t1 non-joinable before main returns, either by calling join or detach on t1. Whether function_1 has finished running on its thread of execution or not is not relevant.