When should I use std::thread::detach? - c++

Sometime I have to use std::thread to speed up my application. I also know join() waits until a thread completes. This is easy to understand, but what's the difference between calling detach() and not calling it?
I thought that without detach(), the thread's method will work using a thread independently.
Not detaching:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called without detach");
});
//some code here
}
Calling with detaching:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called with detach");
});
t.detach();
//some code here
}

In the destructor of std::thread, std::terminate is called if:
the thread was not joined (with t.join())
and was not detached either (with t.detach())
Thus, you should always either join or detach a thread before the flows of execution reaches the destructor.
When a program terminates (ie, main returns) the remaining detached threads executing in the background are not waited upon; instead their execution is suspended and their thread-local objects destructed.
Crucially, this means that the stack of those threads is not unwound and thus some destructors are not executed. Depending on the actions those destructors were supposed to undertake, this might be as bad a situation as if the program had crashed or had been killed. Hopefully the OS will release the locks on files, etc... but you could have corrupted shared memory, half-written files, and the like.
So, should you use join or detach ?
Use join
Unless you need to have more flexibility AND are willing to provide a synchronization mechanism to wait for the thread completion on your own, in which case you may use detach

You should call detach if you're not going to wait for the thread to complete with join but the thread instead will just keep running until it's done and then terminate without having the spawner thread waiting for it specifically; e.g.
std::thread(func).detach(); // It's done when it's done
detach basically will release the resources needed to be able to implement join.
It is a fatal error if a thread object ends its life and neither join nor detach has been called; in this case terminate is invoked.

This answer is aimed at answering question in the title, rather than explaining the difference between join and detach. So when should std::thread::detach be used?
In properly maintained C++ code std::thread::detach should not be used at all. Programmer must ensure that all the created threads gracefully exit releasing all the acquired resources and performing other necessary cleanup actions. This implies that giving up ownership of threads by invoking detach is not an option and therefore join should be used in all scenarios.
However some applications rely on old and often not well designed and supported APIs that may contain indefinitely blocking functions. Moving invocations of these functions into a dedicated thread to avoid blocking other stuff is a common practice. There is no way to make such a thread to exit gracefully so use of join will just lead to primary thread blocking. That's a situation when using detach would be a less evil alternative to, say, allocating thread object with dynamic storage duration and then purposely leaking it.
#include <LegacyApi.hpp>
#include <thread>
auto LegacyApiThreadEntry(void)
{
auto result{NastyBlockingFunction()};
// do something...
}
int main()
{
::std::thread legacy_api_thread{&LegacyApiThreadEntry};
// do something...
legacy_api_thread.detach();
return 0;
}

When you detach thread it means that you don't have to join() it before exiting main().
Thread library will actually wait for each such thread below-main, but you should not care about it.
detach() is mainly useful when you have a task that has to be done in background, but you don't care about its execution. This is usually a case for some libraries. They may silently create a background worker thread and detach it so you won't even notice it.

According to cppreference.com:
Separates the thread of execution from the thread object, allowing
execution to continue independently. Any allocated resources will be
freed once the thread exits.
After calling detach *this no longer owns any thread.
For example:
std::thread my_thread([&](){XXXX});
my_thread.detach();
Notice the local variable: my_thread, while the lifetime of my_thread is over, the destructor of std::thread will be called, and std::terminate() will be called within the destructor.
But if you use detach(), you should not use my_thread anymore, even if the lifetime of my_thread is over, nothing will happen to the new thread.

Maybe it is good idea to iterate what was mentioned in one of the answers above: When the main function is finished and main thread is closing, all spawn threads either will be terminated or suspended. So, if you are relying on detach to have a background thread continue running after the main thread is shutdown, you are in for a surprise. To see the effect try the following. If you uncomment the last sleep call, then the output file will be created and written to fine. Otherwise not:
#include <mutex>
#include <thread>
#include <iostream>
#include <fstream>
#include <array>
#include <chrono>
using Ms = std::chrono::milliseconds;
std::once_flag oflag;
std::mutex mx;
std::mutex printMx;
int globalCount{};
std::ofstream *logfile;
void do_one_time_task() {
//printMx.lock();
//std::cout<<"I am in thread with thread id: "<< std::this_thread::get_id() << std::endl;
//printMx.unlock();
std::call_once(oflag, [&]() {
// std::cout << "Called once by thread: " << std::this_thread::get_id() << std::endl;
// std::cout<<"Initialized globalCount to 3\n";
globalCount = 3;
logfile = new std::ofstream("testlog.txt");
//logfile.open("testlog.txt");
});
std::this_thread::sleep_for(Ms(100));
// some more here
for(int i=0; i<10; ++i){
mx.lock();
++globalCount;
*logfile << "thread: "<< std::this_thread::get_id() <<", globalCount = " << globalCount << std::endl;
std::this_thread::sleep_for(Ms(50));
mx.unlock();
std::this_thread::sleep_for(Ms(2));
}
std::this_thread::sleep_for(Ms(2000));
std::call_once(oflag, [&]() {
//std::cout << "Called once by thread: " << std::this_thread::get_id() << std::endl;
//std::cout << "closing logfile:\n";
logfile->close();
});
}
int main()
{
std::array<std::thread, 5> thArray;
for (int i = 0; i < 5; ++i)
thArray[i] = std::thread(do_one_time_task);
for (int i = 0; i < 5; ++i)
thArray[i].detach();
//std::this_thread::sleep_for(Ms(5000));
std::cout << "Main: globalCount = " << globalCount << std::endl;
return 0;
}

Related

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?
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.
You are correct that the thread keeps running if detached after the thread's destructor.
No one on earth hold the resources (unless you make arrangements for someone to). However when your application exits, the application shutdown process will end the thread.
One can still arrange to communicate with and "wait" for a detached thread. In essence, join() is a convenience API so that you don't have to do something like this:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
static int counter = 0;
std::atomic<bool> time_to_quit{false};
std::atomic<bool> has_quit{false};
void func()
{
while (!time_to_quit) {
std::cout<<"running..."<<std::endl;
std::cout<<counter++<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
has_quit = true;
}
int main()
{
{
std::thread t(func);
t.detach();
} // t is released after this line
using namespace std::chrono_literals;
std::this_thread::sleep_for(3s);
time_to_quit = true;
while (!has_quit)
;
std::cout << "orderly shutdown\n";
}
Threads of executions exist independently from the thread objects that you use to manage them in C++. When you detach a thread object, the thread of execution continues running, but the implementation (usually in combination with the Operating System) is responsible for it.

Output of multiple thread executions only happens once? [duplicate]

This question already has answers here:
C++ std::vector of independent std::threads
(4 answers)
Closed 4 years ago.
#include <iostream>
#include <thread>
void func() {
std::cout << "Hello";
}
int main() {
std::vector<std::thread> threads;
int n = 100;
for (int i = 0; i < n; i++) {
std::cout << "executing thread" << std::endl;
threads.push_back(std::thread(func));
}
}
My program prints "executing thread" once and it ends. What is the cause?
After this loop completes the destructor of std::vector<std::thread> is invoked. std::thread destructor calls std::terminate if the thread was neither detached nor joined, like in your case.
To fix that, add the following after the loop:
for(auto& thread : threads)
thread.join();
Make sure you join the threads to wait for them all to complete:
for (auto &thread : threads) {
thread.join();
}
If the program continues after this point and doesn't exit immediately, flush the output since it may be buffered:
std::cout << std::flush;
Even if you don't join, it should still print "executing thread" 100 times.
Perhaps the problem is using "endl" instead of "std::endl"
Once the loop creating the threads is done, your program continues. And it continues to leave the main function which causes all variables defined inside the main function to go out of scope and their life-time ending. This leads to the destruction of the objects, including the vector which then leads to all the thread object in the vector being destructed.
And as noted by others, the destruction of a thread object will lead to program termination if the thread is not joined or detached.
While the other answers tell you to join the threads (which IMO is the recommended solution here) there is another possible solution: To detach the threads.
While this will lead to the std::terminate function to be called and prematurely terminate your program, this will lead to another problem, as leaving the main function ends the process and all its threads.
If you for some reason what your threads to continue to live on after the main function exits, you need to detach the threads and exit the "main thread" using an operating-system specific function. This will leave the process running with all your created threads still chugging along.

Relation between running Thread and the thread object

While learning basic thread management, I found difficulty in understanding these lines (in bold) from a book.
Once you’ve started your thread, you need to explicitly decide whether
to wait for it to finish (by joining with it—see section 2.1.2) or
leave it to run on its own (by detaching it—see section 2.1.3). If you
don’t decide before the std::thread object is destroyed, then your
program is terminated (the std::thread destructor calls
std::terminate()). It’s therefore imperative that you ensure that the
thread is correctly joined or detached, even in the presence of
exceptions. See section 2.1.3 for a technique to handle this scenario.
Note that you only have to make this decision before the std::thread
object is destroyed—the thread itself may well have finished long
before you join with it or detach it, and if you detach it, then the
thread may continue running long after the std::thread object is
destroyed.
When does a thread run even after the thread object is destroyed? Anyone have sample code or any reference?
What this means is that the lifetime of the thread is not associated with the lifetime of the thread object.
So the following code:
#include <thread>
#include <iostream>
int main() {
{ //scope the thread object
std::thread thr = std::thread([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread stuff\r\n";
});
thr.detach();
} //thr is destroyed here
std::cout << "thr destroyed, start sleep\r\n";
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "sleep over\r\n";
}
Will output:
thr destroyed, start sleep
Thread stuff
sleep over

Why .join is still necessary when all other thread have finished before the main thread?

Learning C++ multi-threading.
In my example, thread helper1 and helper2 have finished executing before the main thread finished. However, program crashes. I specifically, took out .join() statements, to see how program would behave, expecting no errors, since main() calls std::terminate after two other threads have finished.
void foo()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "t1\n";
}
void bar()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "t2\n";
}
int main()
{
std::cout << "starting first helper...\n";
std::thread helper1(foo);
std::cout << "starting second helper...\n";
std::thread helper2(bar);
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "waiting for helpers to finish..." << std::endl;
//helper1.join();
//helper2.join();
std::cout << "done!\n";
}
I'd say that your question doesn't make sense, because it's based on a false assumption. The only way to know that a thread has finished is when the thread's join() returns. Before join() returns, it is not the case that "the thread has finished". It may be true that some statement within the thread's execution has completed (e.g. the printing of a message, or better, the writing of an atomic variable), but the completion of the thread function itself is not measurable in any way other than by joining.
So none of the threads "have finished" until you join them.
Because std::~thread calls terminate if the associated thread is still joinable:
30.3.1.3 thread destructor [thread.thread.destr]
~thread();
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]
You need to call either .detach() or .join(). Other than that, since you cannot be sure how the operating system schedules your threads, you could end up interrupting your threads any way, so better use .join() from the beginning.
Based on the reference, underlying thread must be joined or detached at the time the destructor is called. The destructor is invoked when main exits, and probably assumes that join or detach has been called.
The code should also not crash, as long as the following two lines are somewhere after helper1 and helper2 are constructed.
helper1.detach()
helper2.detach()
The CPU can schedule the three threads ( main / thread1 / thread2 ) in any order. It might happen that your main doesn't get a time to run and your threads exit. So, you need to keep keep join in main to take care of this case. Scheduling of threads is unpredictable, unless you are using an RTOS.

how a thread can signal when it's finished?

#include <iostream>
#include <boost/thread.hpp>
using std::endl; using std::cout;
using namespace boost;
mutex running_mutex;
struct dostuff
{
volatile bool running;
dostuff() : running(true) {}
void operator()(int x)
{
cout << "dostuff beginning " << x << endl;
this_thread::sleep(posix_time::seconds(2));
cout << "dostuff is done doing stuff" << endl;
mutex::scoped_lock running_lock(running_mutex);
running = false;
}
};
bool is_running(dostuff& doer)
{
mutex::scoped_lock running_lock(running_mutex);
return doer.running;
}
int main()
{
cout << "Begin.." << endl;
dostuff doer;
thread t(doer, 4);
if (is_running(doer)) cout << "Cool, it's running.\n";
this_thread::sleep(posix_time::seconds(3));
if (!is_running(doer)) cout << "Cool, it's done now.\n";
else cout << "still running? why\n"; // This happens! :(
return 0;
}
Why is the output of the above program:
Begin..
Cool, it's running.
dostuff beginning 4
dostuff is done doing stuff
still running? why
How can dostuff correctly flag when it is done? I do not want to sit around waiting for it, I just want to be notified when it's done.
The problem in this example is that there are two instances of dostuff, so the version being set to false in operator() is different then the one in main.
From the thread management documentation:
A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or cannot) be copied, then boost::ref can be used to pass in a reference to the function object. In this case, the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution.
If you don't want to copy the object, use boost::ref:
thread t(boost::ref(doer), 4);
You can't assume the thread will be finished just by sleeping.
You can call join on the thread. This will wait until the thread is done and then resume flow.
For advanced notifying between threads of a certain event happening you can use boost condition.
I'm guessing your problem is actually a bug in your code. From the Boost documentation for thread:
Thread Constructor with arguments
template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);
Preconditions:
F and each An must by copyable or movable.
Effects:
As if thread(boost::bind(f,a1,a2,...)). Consequently, f and each an are copied into internal storage for access by the new thread.
So, I think the thread is modifying its own copy of doer, and not the object whose runnable state you're checking.
The real question isn't how the dostuff thread should send the signal, but rather how the main thread should receive the signal. My favorite method is to use socketpair() to create a local socket connection and then give one socket to the child thread and the other socket to the main thread. The two threads can then use the socket-connection to communicate with each other. In your case, all you would need is for the child thread to send a byte on the socket (or just close its socket file descriptor) just before it exits, and that would be enough to break the main thread out of select() or poll() or whatever it is blocking in and let it know that the child thread has finished its task.
Note that the main thread should still call join() on the child thread's thread-ID (after it receives the child-going-away signal), to make sure that the child thread is really really dead, before freeing any resources... otherwise you risk a race condition of the main thread freeing a resource after the child thread has signalled but before the thread-cleanup routines have completed.