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.
Related
This question already has answers here:
How does thread::detach() work in C++11?
(2 answers)
What happens to a detached thread when main() exits?
(7 answers)
Closed 1 year ago.
I am writing the following c++ code to create a detach thread :
void threadF() {
ofstream f("data") ;
for(int i=1; i<=5; i++) {
f<<"t1:::"<<i<<"\n" ;
f.flush() ;
sleep(1) ;
}
f.close() ;
}
int main() {
thread t1(threadF) ;
cout<<"main #1\n" ;
sleep(2) ;
t1.detach() ;
cout<<"main #2\n" ;
}
When I run this code, I have the following observations :
main exits after 2 secs (as expected)
the detach child thread also seems to be running only for 2secs because the output data file contains only 2 lines.
I expected that the thread should have executed completely and that the output data file should have contained 5 lines. This is not happening
I need an explanation for this behavior.
AS per the ink What happens to a detached thread when main() exits?, does it mean that the detached thread would automatically terminate when the main exits ?
I need an explanation for this behavior.
When main returns, the process is terminated. If there was a thread running, there are no guarantees that it will have a chance to finish.
Furthermore, technically touching any global state after main has returned results in undefined behaviour because all static storage objects will be destroyed by the main thread.
Basically, std::thread::detach is rarely useful because you simply have to use some other way to join the thread instead. There's no standard way to "wait for all detached threads and then stop". There are platform specific ways though (pthread_exit).
This question already has answers here:
Starting thread causing abort()
(2 answers)
std::thread causes program to abort
(1 answer)
Closed 1 year ago.
Why using delete in a thread fails, but not if called synchronously ?
class dummyclass{};
main()
{
vector<dummyclass*> testlist{};
for(int i=0; i<5; i++)
{
auto value = new dummyclass();
testlist.push_back(value);
}
thread cleanuptest([&]() {for (auto x : testlist) delete x;}); // fails (abort())
}
EDIT/COMMENT
detach and join are the right solutions.
In the case main() is actually a method in a bigger program, which continues to live, detach() is interesting.
In the case of unit tests, then calling join() in the destructor of the class to test is cleaner.
The problem with your program is that your main() function exits before the cleanuptest() thread has a chance to run to completion, taking the testlist object with it. So when cleanuptest() runs, it will likely be trying to access a vector that has already been destroyed (or is in the process of being destroyed, depending on the timing of when the threads execute; they are running asynchronously with respect to each other so their relative timing is indeterminate).
The other problem (which is likely the source of the abort() call) is that the std::thread destructor is detecting that you are destroying the thread object without having called either join() or detach() on it first, which is considered a programming error.
The fix is easy, just add this line to the bottom of main():
cleanuptest.join();
The join() method won't return until the child thread has exited, so it will guarantee that testlist remains valid until the child thread is done using it.
Your main is finishing before the thread has a chance to finish which is causing the abort. You should cleanuptest.join() the thread to let it finish before main exits.
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
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.
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;
}