When is std::thread destructor called? - c++

I know that std::thread destructors are called on main exit, or when a thread object goes out of scope.
But is it also destroyed when a function that it is calling is done executing?
If not what happens to such a thread, can I still join() it?

But is it also destroyed when a function that it is calling is done executing? If not what happens to such a thread, can I still join() it?
No it isn't destroyed, but marked joinable(). So yes you can still join() it.
Otherwise as from the title of your question ("When is std::thread destructor called?") and what you say in your post
I know that std::thread destructors are called on main exit, or when a thread object goes out of scope.
It's like with any other instance: The destructor is called when the instance goes out of scope or delete is called in case the instances were allocated dynamically.
Here's a small example code
#include <thread>
#include <iostream>
#include <chrono>
using namespace std::chrono_literals;
void foo() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(foo);
std::this_thread::sleep_for(1s);
std::cout << "t.joinable() is " << t.joinable() << std::endl;
t.join();
}
The output is
Hello from thread!
t.joinable() is 1
See it live.

Related

Code crashes when creating new thread c++

I'm new to C++ and I'm trying to make the console print "after 5 seconds" after 5000 ms. Then print "insta log" immediately after the new thread's declaration.
But doing so crashes with the following error:
"Debug Error!
[PROGRAM PATH]
abort() has been called
"
This is my code:
#include <iostream>
#include <thread>
#include <Windows.h>
#include <ctime>
using namespace std;
void f() {
Sleep(5000);
cout << "after 5 seconds" << endl;
}
int main() {
cout << "starting" << endl;
// Pass f and its parameters to thread
// object constructor as
thread t(&f);
cout << "insta log" << endl;
}
I'm unsure why this is happening. I've searched around and I found a "fix" but it makes my code not behave as intended.
This is the "fix"
#include <iostream>
#include <thread>
#include <Windows.h>
#include <ctime>
using namespace std;
void f() {
Sleep(5000);
cout << "after 5 seconds" << endl;
}
int main() {
cout << "starting" << endl;
// Pass f and its parameters to thread
// object constructor as
thread t(&f);
t.join();
cout << "insta log" << endl; // doesn't print for 5 seconds
}
This removes the error message but yields the main thread for 5 seconds. Which makes my code not work as intended.
Thanks in advance, any help is appreciated!
This removes the error message.
Yes.
but yields the main thread for 5 seconds.
This is not what is happening!
The main thread is waiting for your second thread t to finish (slightly different to yielding).
The problem before was that the main thread was exiting the application (and you are not allowed to have other threads running after the main thread exits (this is because what happens to the children thread is highly depended on the threading implementation and they very wildly).
In the C++ std::thread class they try and compensate for the above behavior by making the destructor terminate() if the current thread leaves scope without the child thread of execution completing.
This means you usually have to call the join() method to wait for the child to exit.
So what you usually do is 1: create a std::thread object that does some work in the background 2: while you do some work locally. Then when you have finished, 3: you call join() and wait for the child object to also finish (if it has already finished this does nothing). Then you can exit scope (and exit the main).
Which makes my code not work as intended.
int main()
{
// STUFF.
// Create your thread.
thread t(&f);
// Print any thing you want.
// i.e. do the work you want to do in main.
cout << "insta log" << endl;
// When you have finished.
// wait for the child to finish.
t.join();
} // now the std::thread::~thread check to make sure the
// child thread of execution is no longer running.
If you had clicked 'retry' in that dialog you would have seen why your code died. Its right here
~thread() noexcept {
if (joinable()) {
_STD terminate();
}
}
in the MSVC implementation of std::thread. The code says that destroying a thread thats still joinable (ie is running) is illegal. I dont know if thats c++ defined behavior, a quick search didnt show me. Anyway when you join the thread, you will wait till its OK to destroy it
Functions are already passed around as pointers, use thread t(f) instead of thread t(&f).
Moreover, since your main() neither lasts longer than the thread or calls a t.join(), the program will end before the thread finishes it's code, so that might be another reason for a crash. In fact it is probably the reason for the crash.
If you want "insta log" to print instantly, then call t.join() at the end of main(). t.join() will wait for the thread t to end before continuing.

When std::thread is destructed and what happen to the shared_ptr if the pointer point to it?

When I create a std::thread instance, when will it be destructed? Is the time when the thread finish its task then it is destructed or it works as a normal object which will be destructed when it will not be used anymore?
//a fake function for std::thread
void func();
void main()
{
auto threadPtr = std::make_shared<std::thread>(func)
threadPtr->join();
// is thread object which threadPtr point destructed in here ?
//... other stuffs ....
}
Is thread object destructed after threadPtr->join()?
Is thread object destructed after threadPtr->join()?
No. join() ends the thread of execution that the std::thread object represents, it does not destroy the std::thread object.
When I create a std::thread instance, when will it be destructed?
It will be destroyed when threadPtr goes out of scope since it is an automatic object(it has automatic storage duration). The std::shared_ptr destructor will call the std::thread destructor, and then it will free the memory it obtained.
The underlying operating system thread may have terminated but that isn't the same as the C++ std::thread object being destructed.
Execute the following:
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
std::mutex cout_mutex;
std::atomic<bool> waiter{true};
void func(){
{
std::lock_guard<std::mutex> guard(cout_mutex);
std::cout << "funky\n";
}
while(waiter);//cheap spin waiting...
}
int main() {
auto threadPtr = std::make_shared<std::thread>(func);
{
std::lock_guard<std::mutex> guard(cout_mutex);
std::cout << "an active thread id: "<<threadPtr->get_id()<<'\n';
}
waiter=false;
threadPtr->join();
std::cout << "terminated thread id: "<< threadPtr->get_id()<<'\n';
return 0;
}
The output varies but possible output here is:
an active thread id: 47441922455296
funky
terminated thread id: thread::id of a non-executing thread
The object contained in threadptr remains valid until destructed but may be referencing a terminated thread.
std::thread is typically an implementation of a wrapper class (or the proxy design pattern). It contains a (possibly empty) reference to what is normally an operating system thread object. When the wrapped thread ends the reference may be made empty.

Checking whether std::thread member of my class is stopped

I have a class which has a std::thread member. I detach it in the constructor, and I wanted to be sure that, when the object is destroyed, the thread is stopped and destroyed too.
How can I achieve this?
I have a class which has a std::thread member
Okay!
I detach it in the constructor
Alright. That means you don't want the class to manage the thread any more. No problem.
and I wanted to be sure that when the object is destroyed, the thread is stopped and destroyed too
Oh, so… huh. You do want the class to manage the thread? Interesting.
Don't detach the thread.
It is literally the anti-what-you-want-to-do and single-handedly responsible for your problem.
Once you detach a std::thread you no longer have control of that thread. the std::thread object releases it and all the resources of the thread will not be freed until the thread finishes or the process(program) exits. If you want to stop a detached thread you would have to send a signal to it with some sort of flag(std::atomic<bool> comes to mind) or std::condition_variable to have it end itself.
If you want the thread to live with the class and then once the class is destroyed then terminate the thread then you do not want to call detach. Instead what you would do is call join() in the destructor which stops the destructor from running until the thread finishes. Once it does then the destructor will continue and you will know that the thread has ended and everything has been cleaned up.
Let's see through an example how can an std::thread be handled to be ensured that will be stopped and destroyed when the enclosure object is destroyed:
#include <mutex>
#include <condition_variable>
#include <thread>
#include <atomic>
#include <cstdlib>
#include <ctime>
#include <iostream>
class ThreadTester {
public:
ThreadTester() : isAlive(true), randomNumber(0) {
// Start the background operation.
myThread = std::thread(&ThreadTester::createRandom, this);
}
virtual ~ThreadTester() {
{
// Stop the running thread.
std::unique_lock<std::recursive_mutex> lk(mutex);
isAlive = false;
condition.notify_all();
}
// Join the stopped thread.
if(myThread.joinable())
myThread.join();
}
int getRandom() const {
return randomNumber;
}
private:
void createRandom() {
std::unique_lock<std::recursive_mutex> lk(mutex);
// Do something with 250ms intervall while the isAlive is true.
while(isAlive) {
condition.wait_for(lk, std::chrono::milliseconds(250));
if(isAlive) {
randomNumber = rand() % 100;
}
}
}
std::recursive_mutex mutex;
std::condition_variable_any condition;
bool isAlive;
std::thread myThread;
std::atomic_int randomNumber;
};
int main() {
srand(time(NULL));
const ThreadTester tester;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Test: " << tester.getRandom() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Test: " << tester.getRandom() << std::endl;
return 0;
}
I my example I hold the thread until it become stopped to make it sure it can be destroyed safely. I don't think so that detaching a thread is a good practice.

std::thread thread spun off in object, when does it terminate?

If I spin off an std::thread in the constructor of Bar when does it stop running? Is it guaranteed to stop when the Bar instance gets destructed?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
...
void foo() {
while (true) {//do stuff//}
}
private:
std::thread thread;
};
EDIT: How do I correctly terminate the std::thread in the destructor?
If I spin off an std::thread in the constructor of Bar when does it
stop running?
the thread will run as long as it executing the callable you provided it, or the program terminates.
Is it guaranteed to stop when the Bar instance gets destructed?
No. In order to guarantee that, call std::thread::join in Bar destructor.
Actually, if you hadn't call thread::join or thread::detach prior to Bar::~Bar, than your application will be terminated by calling automatically to std::terminate. so you must call either join (preferable) or detach (less recommended).
you also want to call therad::join on the object destructor because the spawned thread relies on the object to be alive, if the object is destructed while your thread is working on that object - you are using destructed object and you will have undefined behavior in your code.
Short answer: Yes and no. Yes, the thread ends, but not by the usual way (killing the thread), but by the main thread exiting due to a std::terminate call.
Long answer: The thread can only be safely destructed when the underlying function (thread) has finished executing. This can be done in 2 ways
calling join(), which waits for the thread to finish (in your case, never)
calling detach(), which detaches the thread from the main thread (in this case, the thread will end when the main thread closes - when the program terminates).
If the destructor is called if all of those conditions don't apply, then std::terminate is called:
it was default-constructed
it was moved from
join() has been called
detach() has been called
The C++ threading facilities do not include a built-in mechanism for terminating a thread. Instead, you must decide for yourself: a) a mechanism to signal the thread that it should terminate, b) that you do not care about the thread being aborted mid-operation when the process terminates and the OS simply ceases to run it's threads any more.
The std::thread object is not the thread itself but an opaque object containing a descriptor/handle for the thread, so in theory it could be destroyed without affecting the thread, and there were arguments for and against automatic termination of the thread itself. Instead, as a compromise, it was made so that destroying a std::thread object while the thread remained running and attached would cause the application to terminate.
As a result, In it's destructor there is some code like this:
~thread() {
if (this->joinable())
std::terminate(...);
}
Here's an example of using a simple atomic variable and checking for it in the thread. For more complex cases you may need to consider a condition_variable or other more sophisticated signaling mechanism.
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this] () { work(); }) {}
void cancel() { running_ = false; }
~S() {
if ( running_ )
cancel();
if ( thread_.joinable() )
thread_.join();
}
private:
void work() {
while ( running_ ) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
Live demo: http://coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1

Why do I need to join a thread even if I use std::future::get?

void
set_string(std::promise<std::string>& p)
{
p.set_value("set from thread");
}
int
main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread t(&set_string, std::ref(p));
std::cout << f.get() << std::endl;
t.join();
}
Why do I need to call t.join() after I call f.get()? I thought that f.get() will block the main thread until it can get the result and that would mean that the thread has already finished.
Because even after thread finishes execution it is still joinable. You can call detach to allow independend execution. In this case you might want to use set_value_at_thread_exit member of promise to lessen chance that main finishes before thread:
#include <iostream>
#include <string>
#include <thread>
#include <future>
void set_string(std::promise<std::string>& p)
{
p.set_value_at_thread_exit("set from thread");
}
int main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread(&set_string, std::ref(p)).detach();
std::cout << f.get() << std::endl;
}
http://coliru.stacked-crooked.com/a/1647ffc41e30e5fb
I believe the rationale for threads is simply that you either explicitly join them or that you explicitly detach them, but if a thread object gets destroyed before either happened, you probably have a problem with your design. The decision was not to assume you want to detach it or join it when the destructor is called, because either one is a bad guess in most situations.
Further, concerning your case, it doesn't matter where the future is set from. The requirements for the thread object are not touched by how it triggers the future, they stay the same.
Note that in your case, since you don't care about the thread any longer, you could simply detach it.