I want to create a new thread inside a while loop but it makes the program instantly crash on start.
Any ideas on how to fix this?
#include <thread>
using namespace std;
void function1()
{
}
int main()
{
while(true)
{
thread thread(function1);
}
return 0;
}
When your std::thread goes out of scope, its destructor is called. The std::thread destructor calls std::terminate() if the thread is still active. You MUST join() or detach() the std::thread object before it is destroyed.
Related
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.
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
std::thread::join does not return, even if the thread routine is exited.
Guess, I have a class.
class A
{
public:
A()
{
this->thr = std::thread(&A::foo, this);
}
~A()
{
this->join();
}
void join()
{
this->cond.notify_all();
if (this->thr.joinable())
{
this->thr.join();
}
}
private:
void foo()
{
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
this->cond.wait(lck);
MessageBox(L"I'm done!");
}
private:
std::thread thr;
std::condition_variable cond;
};
My application contains the only instance of A. It is a global variable.
If A::join is called from the destructor, std::thread::join blocks forever.
If I call A::join manually (e.g. before exiting main), everything is alright.
My main looks like this:
A a;
int main()
{
auto timeout = std::chrono::seconds(3);
std::this_thread::sleep_for(timeout);
// a.join();
}
By the way, MessageBox is always executed.
Is that the same problem as here?
Yes it is the same bug as in the referenced link since your example also hangs on _Thrd_join. You could be interrested in this question which contains a far more detailed analysis.
from your comment
"It doesn't seem to be a great solution. I works, but what if the main
is not so trivial? There're a lot of different ways of exiting from my
application. Thus, I've got to join my threads manually every time I
need it?"
how about making A a std::unique_ptr within your main. that way, no matter how your main exits, it'll always destroy A before exiting main() and you won't have this problem.
following code is a scoped thread example in c++ concurrency in action. but i has a question when run this example in xcode5.1, because the Scoped_thread t is join in its destructor function, destructor of t is run in the end of thread main()? so no matter how long I has the main() thread sleep, the main's output is before the t's output, but the answer is not? anyone can help me explain this?
#include <iostream>
#include <algorithm>
#include <thread>
#include <chrono>
using namespace std;
struct Scoped_thread
{
std::thread sthread;
Scoped_thread(std::thread tmp):sthread(std::move(tmp))
{
if (!sthread.joinable())
{
cout<<"error on contructor a scoped thread"<<endl;
}
}
~Scoped_thread()
{
sthread.join();
}
Scoped_thread(Scoped_thread& tmp) = delete;
Scoped_thread& operator =(const Scoped_thread& tmp) = delete;
};
void hello_scoped_thread()
{
cout<<"this is scoped thread output"<<endl;
}
int main()
{
Scoped_thread t((std::thread(hello_scoped_thread)));
//std::this_thread::sleep_for(std::chrono::seconds(10));
cout<<"this is in main thread"<<endl;
return 0;
}
edit plus:i want to know when the main thread known t thread is joined, when main do destruct the t? / during compiler parse the code or sometime like this?
The thread is running asynchronously, so there should be not too much concern about the order of actions between the thread and main. The actions are normally done as fast as possible, so when 1 thread waits, the others can just continue.
The scoped thread class just takes care that the main thread waits until the new thread finishes at the end of the scope, which is the end of the main() function, by joining.
After using threads for a while, I got into a situation where I needed a thread to run forever until a a function (or any sort of event) was called. To do this I created a bool value to control a while loop inside the function that was executed by the thread, but I quickly noticed that external variables are not updated after a thread starts running, causing the thread to never stop when it was asked to.
Heres some simple code to represent the issue:
#include <cstdio>
#include <thread>
#include <chrono>
class A {
public:
A();
void startThread();
void endThread();
private:
void threadCall();
bool active;
};
int main() {
A threadThing;
threadThing.startThread();
printf("[M] Thread Created\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
threadThing.endThread();
printf("[M] Thread Killed\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
A::A() {
active = false;
}
void A::startThread() {
active = true;
std::thread AThread(&A::threadCall, *this);
AThread.detach();
}
void A::endThread() {
active = false;
}
void A::threadCall() {
printf("[T] Thread Started\n");
while (active) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}
The expected result of this would be that the main function starts the thread, the thread says it started, then 4 seconds later the thread is killed and the thread says it ended, when in reality the thread never says it ends. Is there a way to let the thread access the 'active' variable, or is my approach to this problem incorrect altogether? (Side note, I did try to figure this out on my own but only got stuff like local thread storage which seems like its only for storage inside of threads, not access to the outside but I could be wrong)
The problem is with the constructor of std::thread, it copies/moves by default.
std::thread AThread(&A::threadCall, *this);
this copies the object into the new thread, so checking the active variable in the new object has no effect.
you can remove the *
std::thread AThread(&A::threadCall, this);
you pass the object pointer into the new thread, it will call like the method like this(*this).threadCall().
Edit: as the comments say, this is not guarantee to be thread safe, you need to use std::atomic<bool> to be safe.
What you need to do is pass an A class pointer as an argument to your function that is your thread.
void A::startThread()
{
active = true;
std::thread AThread(threadCall, this);
AThread.detach();
}
void A::threadCall(A *aClass)
{
printf("[T] Thread Started\n");
while (aClass->active)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}