4

If I create an std::thread that terminates before I am able to call detatch() on it, what is the expected behavior? Should an exception be thrown due to the fact that joinable is already false?

If this is so, then is there a way to create a thread which is initialized into a detached state so that I can avoid this error?

Example:

void func()
{
    // do something very trivial so that it finishes fast
    int a = 1;
}

void main()
{
    thread trivial(func);
    trivial.detach();
}

I realize that it isn't really practical to spawn a thread to do trivial work in practice, however I did manage to run into this behavior, and I was curious to know if there is a way around it...

Michael Landes
  • 969
  • 1
  • 8
  • 13
  • 6
    The result of `joinable()` does not depend on whether the thread has finished execution. In your scenario, `joinable()` does not in fact become `false` until you call `detach()`. There is no problem here in need of a workaround. – Igor Tandetnik Dec 10 '14 at 05:53
  • 5
    `A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.` – Alex F Dec 10 '14 at 05:54
  • Good points. I am getting this behavior in Visual Studio 2012. Perhaps some kind of optimization error? – Michael Landes Dec 10 '14 at 12:01
  • Alex Farber quote comes from http://en.cppreference.com/w/cpp/thread/thread/joinable – Gabriel Dec 30 '14 at 18:49

2 Answers2

2

Join and detach have the same requirement, they have to be joinable. So I think doing the joinable check should suffice.

If(trivial.joinable())
    trivial.detach();

The documentation states:

A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.

So my guess would be that the detached thread will cease to exist right away. But it definitily can be created.

Note: It's good practice to always call joinable() before joining or detaching a thread.

Community
  • 1
  • 1
laurisvr
  • 2,724
  • 6
  • 25
  • 44
  • 1
    This of course contains a race condition as it could become unjoinable after the check but before the detach. – jcoder Aug 12 '15 at 15:21
  • @jcoder That would be true if the tread would become unjoinable in the meantime. How do you envision this happening? – laurisvr Aug 12 '15 at 15:30
  • If a thread is indeed finished and you want to delete the thread. Is `detach()` faster vs `join()`? I guess so, right? – Melroy van den Berg Dec 31 '21 at 01:26
  • @jcoder if the thread became unjoinable between the joinable() and detach() calls then that's the least of your worries as the developer. Something else is causing undefined behavior, and the race condition is just the manifestation of that problem. It means that other places of the code are moving the thread object during the call, which is a big nono in the first place. – Everyone May 25 '23 at 18:19
1

The thread object will be destructed when its scope will be done. To make sure that object finished its job you need either call join or detach.

Tomas
  • 176
  • 3