According to the documentation here and here, the join method of a C++11 thread will throw a std::system_error if joinable() == false. Thus the natural way to wait for a thread to complete execution is something along the lines of:
if (thread2.joinable()) thread2.join();
However, this has the possibility to throw a std::system_error. Consider thread 1 calls thread2.joinable(), returns true, indicating that the thread2 is still running. Then the scheduler pauses thread1 and switches contexts to thread 2. Thread 2 completes, and then thread 1 resumes. Thread 1 calls thread2.join(), but thread2 has already completed, and as a result, std::system_error is thrown.
A possible solution is to wrap the whole thing in a try block:
try {
thread2.join();
catch (std::system_error &e) {}
But then when a legitimate std::system_error is thrown, possibly to indicate that the thread failed to join, the program continues on, acting as though everything is fine and dandy. Is there a proper way to join a thread besides using a try/catch block like this?
joinable does not do what you think it does. All it does is return whether the thread object is not associated with a thread. However, thread::join will fail if the thread object also represents the current thread. So the only reason for thread::join to fail due to lack of joinable is if you tried to join with yourself.
A completed thread (which isn't your own) is still perfectly joinable.
Related
In a std::thread, an exception is throw if I call join() and the thread is not joinable.
So I do :
if (thread.joinable())
thread.join();
Now imagine that the thread is terminated after the joinable() and before the join() (due to thread scheduling).
Is this case possible in the worth situation ? Do I really need to use a try / catch around join() ?
Now imagine that the thread is terminated after the joinable() and before the join() (due to thread scheduling).
If thread just terminated it does not become not joinable, std::thread::join() will just successfully return immediately in such case as it said in documentation for std::thread::joinable():
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.
It can become not joinable if you call std::sthread::join() for the same thread concurrently.
Is this case possible in the worth situation ? Do I really need to use a try / catch around join() ?
Only if you try to call std::thread::join() for the same thread from multiple threads. You better avoid that and have only one thread manage others.
It is not thread safe. If you have more than one thread that can call your snippet at any time, you may experience a race condition. The only real way to protect against this is by wrapping your snippet in an std::mutex shared by the threads calling said snippet.
Given below:
void test()
{
std::chrono::seconds dura( 20 );
std::this_thread::sleep_for( dura );
}
int main()
{
std::thread th1(test);
std::chrono::seconds dura( 5 );
std::this_thread::sleep_for( dura );
return 0;
}
main will exit after 5 seconds, what will happen to th1 that's still executing?
Does it continue executing until completion even if the th1 thread object you defined in main goes out of scope and gets destroyed?
Does th1 simply sits there after it's finished executing or somehow gets cleaned up when the program terminates?
What if the thread was created in a function, not main - does the thread stays around until the program terminates or when the function goes out of scope?
Is it safe to simply not call join for a thread if you want some type of timeout behavior on the thread?
If you have not detached or joined a thread when the destructor is called it will call std::terminate, we can see this by going to the draft C++11 standard we see that section 30.3.1.3 thread destructor says:
If joinable(), calls std::terminate(). Otherwise, has no effects. [
Note: Either implicitly detaching or joining a joinable() thread in
its destructor could result in difficult to debug correctness (for
detach) or performance (for join) bugs encountered only when an
exception is raised. Thus the programmer must ensure that the
destructor is never executed while the thread is still joinable. —end
note ]
as for a rationale for this behavior we can find a good summary in (Not) using std::thread
Why does the destructor of a joinable thread have to call
std::terminate? After all, the destructor could join with the child
thread, or it could detach from the child thread, or it could cancel
the thread. In short, you cannot join in the destructor as this would
result in unexpected (not indicated explicitly in the code) program
freeze in case f2 throws.
and an example follows and also says:
You cannot detach as it would risk the situation where main thread
leaves the scope which the child thread was launched in, and the child
thread keeps running and keeps references to the scope that is already
gone.
The article references N2802: A plea to reconsider detach-on-destruction for thread objects which is argument against the previous proposal which was detach on destruction if joinable and it notes that one of the two alternatives would be to join which could lead to deadlocks the other alternative is what we have today which is std::terminate on destruction if joinable.
std::thread::~thread()
If *this has an associated thread (joinable() == true), std::terminate() is called
Source: http://en.cppreference.com/w/cpp/thread/thread/~thread
This means that program like this is not at all well-formed or safe.
Note, however, that boost::thread::~thread() calls detach() instead in this case.
(as user dyp stated in comments, this behavior is deprecated in more recent versions)
You could always workaround this using RAII. Just wrap your thread inside another class, that will have desired behavior on destruction.
In C++11, you must explicitly specify 'what happens' when the newly created thread goes out of scope (our it's dtor is called). Sometimes, when we are sure that the main thread, is continuing, and our threads are acting as 'pipeline', it is safe to 'detach()' them; and sometimes when we are waiting for our WORKER threads to complete their operations, we 'join()' them.
As this says, the programmer must ensure that the destructor is never executed while the thread is still joinable.
Specify your multi-threaded strategy. In this example, std::terminate() is called.
I have a strange issue with C++11 threads.
Unfortunately I cannot paste the full example (given the complexity) and I cannot replicate the issue on a simpler example.
So the problem is that I have a thread which is running (nor join nor detach has been called on it).
At some point another thread wants to stop this thread. The implementation simply set a boolean variable to false, and the call the join to wait for thread termination.
Well, the problem is the join.
I checked that the current thread (calling the join) is different from the joined thread and joinable() returns true.
Nevertheless this exception occurs:
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
This happens on macOS 10.11 but I had a colleague of mine test it on linux and it does not occur.
Any clue?
This might happen if you call fork() after creating additional threads in parent process. One important thing that differs the child process from the parent is that the child has only one thread.
So all C++ code which thinks there's a thread will be fooled and join() will throw
"No such process". In this case because native call will return ESRCH.
You shouldn't create threads before calling fork().
Given below:
void test()
{
std::chrono::seconds dura( 20 );
std::this_thread::sleep_for( dura );
}
int main()
{
std::thread th1(test);
std::chrono::seconds dura( 5 );
std::this_thread::sleep_for( dura );
return 0;
}
main will exit after 5 seconds, what will happen to th1 that's still executing?
Does it continue executing until completion even if the th1 thread object you defined in main goes out of scope and gets destroyed?
Does th1 simply sits there after it's finished executing or somehow gets cleaned up when the program terminates?
What if the thread was created in a function, not main - does the thread stays around until the program terminates or when the function goes out of scope?
Is it safe to simply not call join for a thread if you want some type of timeout behavior on the thread?
If you have not detached or joined a thread when the destructor is called it will call std::terminate, we can see this by going to the draft C++11 standard we see that section 30.3.1.3 thread destructor says:
If joinable(), calls std::terminate(). Otherwise, has no effects. [
Note: Either implicitly detaching or joining a joinable() thread in
its destructor could result in difficult to debug correctness (for
detach) or performance (for join) bugs encountered only when an
exception is raised. Thus the programmer must ensure that the
destructor is never executed while the thread is still joinable. —end
note ]
as for a rationale for this behavior we can find a good summary in (Not) using std::thread
Why does the destructor of a joinable thread have to call
std::terminate? After all, the destructor could join with the child
thread, or it could detach from the child thread, or it could cancel
the thread. In short, you cannot join in the destructor as this would
result in unexpected (not indicated explicitly in the code) program
freeze in case f2 throws.
and an example follows and also says:
You cannot detach as it would risk the situation where main thread
leaves the scope which the child thread was launched in, and the child
thread keeps running and keeps references to the scope that is already
gone.
The article references N2802: A plea to reconsider detach-on-destruction for thread objects which is argument against the previous proposal which was detach on destruction if joinable and it notes that one of the two alternatives would be to join which could lead to deadlocks the other alternative is what we have today which is std::terminate on destruction if joinable.
std::thread::~thread()
If *this has an associated thread (joinable() == true), std::terminate() is called
Source: http://en.cppreference.com/w/cpp/thread/thread/~thread
This means that program like this is not at all well-formed or safe.
Note, however, that boost::thread::~thread() calls detach() instead in this case.
(as user dyp stated in comments, this behavior is deprecated in more recent versions)
You could always workaround this using RAII. Just wrap your thread inside another class, that will have desired behavior on destruction.
In C++11, you must explicitly specify 'what happens' when the newly created thread goes out of scope (our it's dtor is called). Sometimes, when we are sure that the main thread, is continuing, and our threads are acting as 'pipeline', it is safe to 'detach()' them; and sometimes when we are waiting for our WORKER threads to complete their operations, we 'join()' them.
As this says, the programmer must ensure that the destructor is never executed while the thread is still joinable.
Specify your multi-threaded strategy. In this example, std::terminate() is called.
I've read a few sources on proper methods of bubbling a message out from a thread to all other threads to exit gracefully (every thread performs it's own exit routine). Of these, I liked the idea of a global atomic boolean that can be flagged from any thread, and all other threads check this flag to perform an exit routine - when all threads are joined, the main thread can then exit the application.
Purely computation threads would probably be handled differently, right?
Is this efficient and safe? Is there a better way to do this?
Thanks!
I'm not a fan of threads checking boolean (or other) status variables to know when to do what, because it's wasteful. The threads would have to spin, constantly checking the variable to see if there are new instructions. This burns the CPU.
A better option is to create a semaphore or in Windows an event, and have all the threads wait on that. The threads can sleep while they arent busy, and wont steal time slices from other threads doing real work simply to check a variable.
In Windows, I use QueueUserAPC to call a function which throws an exception, causing threads to exit cleanly.
I wrote more about the details in this answer here:
How do I guarantee fast shutdown of my win32 app?
In summary, here's what happens:
Say thread A wants to terminate thread B (and then C, D, ...)
Thread A calls QueueUserAPC(), passing the handle to thread B and the address of a function which will throw an Exception of class MyThreadExit.
Thread B runs normally until it calls something that checks for alertable waits. Maybe WaitForSingleObjectEx, maybe SleepEx, or something else.
At this point, thread B runs the APC function passed earlier, causing the exception to be thrown in Thread B.
All stack-allocated objects get automatically destructed correctly as the exception makes thread B 'unwind' its stack.
The outermost thread function of thread B will catch the exception.
Thread B now exits, possibly signalling to Thread A that it's done.