Waiting for a std::thread to finish - c++

I am trying to clean up gracefully on program termination, so I'm calling join() on a std::thread to wait for it to finish. This simply seems to block the main thread forever, but I don't understand why, because the worker thread is an (almost) empty loop like this:
void GameLoop::Run()
{
while (run)
{
// Do stuff...
}
std::cout << "Ending thread...\n";
}
I'm setting run to false before joining, of course. Now, I'm suspecting it's got something to do with it being a member function and being called upon object destruction. I'm creating the thread like this: runThread.reset(new thread(&GameLoop::Run, this));, where runThread is unique_ptr<std::thread> and a member of GameLoop. The join() call comes in the destructor of the GameLoop object.
Maybe the loop thread cannot finish if its object is in the process of being destroyed? According to the debugger the loop thread lingers on in the dark depths of msvcr120d.dll. If so, how would you handle it?
Beware: new to std::thread here!
Update: This is my call to join in the destructor:
run = false;
if (runThread->joinable())
{
runThread->join();
}
Update 2: If I remove the join() I get an exception raised by ~thread()!

Of course, when you join a thread that doesn't cause the thread to terminate. It simply blocks until that thread dies of natural (or unnatural) causes.
In order to clean up a multithreaded application gracefully, you need to somehow tell the worker thread that it is time to die, and then wait for the death to happen. The "wait for death to happen" part is what join is for.

Ahh, apparently there's a bug in the runtime library. Threads are not ended successfully in destructors of static objects according to this question. My GameLoop is a non-static object contained in a static GameSystem. I'll check whether this is true and update.
Yep, confirmed. Just my luck to hit a bug on first use!

Related

Multithreading a while loop in c++

I've started c++ (coming from a c# background), and in my program I need to run a while true loop, but since it is an imgui program the ui freezes up completely since I'm using Sleep() in the loop. I need to create a new thread but everything I've found online is just
std::thread nThread(Method);
nThread.join();
Now, the issue with this is it doesn't work at all since, I'm assuming, it's a while loop that's always running. I want to do the c++ equivalent of Thread thread = new Thread(method) and thread.Start(); in c#. If anyone can help me, I'd appreciate it.
t.join() waits for thread t to die. If you don't want the method that started the thread to wait for it, then don't join() it.
But note! The C++ library will get angry with you if you allow the thread object to be destroyed while the thread still is running. (The destructor will throw an exception.) If you want to tell the library, "Shut up! I know what I'm doing," you can detach the thread from the object. But usually it's a cleaner design if you can arrange for the object to live for as long as you need the thread to run.
Try a simple example and work from there.
void myFunc()
{
try
{
int x = 0;
while (x < 10)
{
sleep(1000);
std::cout<<"Thread is running"<<std::endl;
x++;
}
}
catch(Interrupted_Exception&) {
cout << "Caught Interrupted_Exception" << endl;
}
}
int main()
{
std::cout<<"Starting main"<<std::endl;
std::thread nThread(myFunc);
std::cout<<"Thread is running. Waiting for it to complete"<<std::endl;
nThread.interrupt();//in case the thread is sleeping
nThread.join();
std::cout<<"All done. Exiting"<<std::endl;
return 0;
}
Join means that the main thread has to wait for the worker thread. It's a way to ensure that the worker thread terminates before the caller. You only want to do that when you are terminating the program, in your case when the GUI is being close. Since at that time you want to tell the worker thread to stop right away, you call interrupt() on tell it to stop sleeping.
In the example, you can comment out the interrupt call so that the worker thread runs to completion.
There is no direct equivalent of that in the standard C++ library. When you use std::thread, the new thread starts immediately. You can simulate delayed start behaviour by making the thread stuck on a locked in advance mutex, then release mutex when you want the thread action to run actually. Aftwerwards you have to either join the thread or make it detached, otherwise std::thread destructor will throw an exception.
If you are on Windows, you can try to use Windows API directly (CreateThread() with flag CREATE_SUSPENDED, then ResumeThread() and finally posssibly TerminateThread() - if thread has sort of endless loop which never terminates in itself).
There is a way you can approach this and is using std::future and std::async with std::launch::async mode and throwing the function with the loop there.
std::future allows you to run a thread in the background and then after running give back the control to the parent thread so the program's flow can go as normal.
so you could have a boolean for the while and when std::future gives you back the control then you could modify this bool in the parent or main thread.

What happens to a thread, waiting on condition variable, that is getting joined?

I've got a class named TThreadpool, which holds member pool of type std::vector<std::thread>>, with the following destructor:
~TThreadpool() {
for (size_t i = 0; i < pool.size(); i++) {
assert(pool[i].joinable());
pool[i].join();
}
}
I'm confident that when destructor is called, all of the threads are waiting on a single condition variable (spurious wakeup controlled with always-false predicate), and joinable outputs true.
Reduced example of running thread would be:
void my_thread() {
std::unique_lock<std::mutex> lg(mutex);
while (true) {
my_cond_variable.wait(lg, [] {
return false;
});
# do some work and possibly break, but never comes farther then wait
# so this probably should not matter
}
}
To check what threads are running, I'm launching top -H. At the start of the program, there are pool.size() threads + 1 thread where TThreadpool itself lives. And to my surprise, joining these alive threads does not remove them from list of threads that top is giving. Is this expected behaviour?
(Originally, my program was a bit different - I made a simple ui application using qt, that used threadpool running in ui thread and other threads controlled by threadpool, and on closing the ui window joining of threads had been called, but QtCreator said my application still worked after I closed the window, requiring me to shut it down with a crash. That made me check state of my threads, and it turned out it had nothing to do with qt. Although I'm adding this in case I missed some obvious detail with qt).
A bit later, I tried not asserting joinable, but printing it, and found out the loop inside Threadpool destructor never moved further than first join - the behaviour I did not expect and cannot explain
join() doesn't do anything to the child thread -- all it does is block until the child thread has exited. It only has an effect on the calling thread (i.e. by blocking its progress). The child thread can keep running for as long as it wants (although typically you'd prefer it to exit quickly, so that the thread calling join() doesn't get blocked for a long time -- but that's up to you to implement)
And to my surprise, joining these alive threads does not remove them from list of threads that top is giving. Is this expected behaviour?
That suggests the thread(s) are still running. Calling join() on a thread doesn't have any impact on that running thread; simply the calling thread
waits for the called-on thread to exit.
found out the loop inside Threadpool destructor never moved further than first join
That means the first thread hasn't completed yet. So none of the other threads haven't been joined yet either (even if they have exited).
However, if the thread function is implemented correctly, the first thread (and all other threads in the pool) should eventually complete and
the join() calls should return (assuming the threads in the pool are supposed to exit - but this doesn't need to true in general.
Depending on application, you could simply make the threads run forever too).
So it appears there's some sort of deadlock or wait for some resource that's holding up one or more threads. So you need to run through a debugger.
Helgrind would be very useful.
You could also try to reduce the number of threads (say 2) and to see if the problem becomes reproducible/obvious and then you could increase the threads.

Amateur can't understand std::thread usage

I hereby pardon for such a general title.
I am writing a physical simulation application which displays data in 3D using OpenGL, and one of the functions which is responsible for some heavy calculations is appearing to hold the performance down a bit. I would like them to be done "on the background" without freezing the application for a few seconds. However, std::thread doesn't seem to work in my case.
The function I am trying to thread has a lot of computations in it, it allocates some memory here and there, calls other functions and uses classes, if that matters. I've created a wrapper function, from which I try to start a thread:
void WrapperFunction(void)
{
std::thread t(DoSomethingSerious);
t.join();
}
However, it appears that it has zero effect, just like if I called DoSomethingSerious directly.
What could be the problem?
join() waits for the thread to finish, before proceeding. That's what joining a thread means.
You have two options.
1) Instantiating a std::thread, and proceed to do whatever else needs to be done, and only join the thread once everything is done.
2) detach() the thread. The detached thread will continue to execute independently, and cannot be joined any more. In this case, you will have to make other arrangements for waiting until the thread stops.
However, it appears that it has zero effect.
Sure, your code in the main thread is just suspended until everything in the asynchronous thread is finished.
If you have intermediate actions between starting the thread and doing the join(), you should notice the effect:
void WrapperFunction(void) {
std::thread t(DoSomethingSerious);
// Do something else in parallel
t.join();
}
That is because you directly call t.join(). The std::thread::join function waits for the thread to finish before returning. As you yourself notice, the effect is that there is no difference from just calling the function.
More useful would be to do something else between the thread creration and where you wait for the thread. Something like the following pseudo-code:
void WrapperFunction(void)
{
// Create thread
std::thread t(DoSomethingSerious);
// Lots
// of
// code
// doing
// other
// things
// Wait for thread to finish
t.join();
}

Does QThread::quit() immediately end the thread or does it wait until returning to the event loop?

There are a lot of Qt multi-threading tutorials out there that state that a QThread can be stopped safely using the following two lines.
qthread.quit(); // Cause the thread to cease.
qthread.wait(); // Wait until the thread actually stops to synchronize.
I have a lot of code doing this, and in most cases of stopping thread, I'll always set my own cancel flag and check it often during execution (as is the norm). Until now, I was thinking that calling quit would perhaps cause the thread to simply no longer execute any waiting signals (e.g. signals that are queued will no longer have their slots called) but still wait on the currently executing slot to finish.
But I'm wondering if I was right or if quit() actually stops the execution of the thread where it's at, for instance if something is unfinished, like a file descriptor hasn't been closed, it definitely should be, even though in most cases my worker objects will clean up those resources, I'd feel better if I knew exactly how quit works.
I'm asking this because QThread::quit() documentation says that it's "equivalent to calling QThread::exit(0)". I believe this means that the thread would immediately stop where it's at. But what would happen to the stackframe that quit was called in?
QThread::quit does nothing if the thread does not have an event loop or some code in the thread is blocking the event loop. So it will not necessarily stop the thread.
So QThread::quit tells the thread's event loop to exit. After calling it the thread will get finished as soon as the control returns to the event loop of the thread.
You will have to add some kind of abort flag if you are blocking event loop for example by working in a loop. This can be done by a boolean member variable that is public or at least has a public setter method. Then you can tell the thread to exit ASAP from outside (e.g. from your main thread) by setting the abort flag. Of course this will require your thread code to check the abort flag at regular intervals.
You may also force a thread to terminate right now via QThread::terminate(), but this is a very bad practice, because it may terminate the thread at an undefined position in its code, which means you may end up with resources never getting freed up and other nasty stuff. So use this only if you really can't get around it. From its documentation:
Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
I think this is a good way to finish a thread when you are using loops in a thread:
myThread->m_abort = true; //Tell the thread to abort
if(!myThread->wait(5000)) //Wait until it actually has terminated (max. 5 sec)
{
myThread->terminate(); //Thread didn't exit in time, probably deadlocked, terminate it!
myThread->wait(); //We have to wait again here!
}
In case, if you want to use Qt's builtin facility then try QThread::requestInterruption().
Main thread
struct X {
QThread m_Thread;
void Quit ()
{
m_Thread.quit();
m_Thread.requestInterruption();
}
};
Some Thread referred by X::m_Thread
while(<condition>) {
if(QThread::currentThread()->isInterruptionRequested())
return;
...
}
As per the documentation:
void QThread::requestInterruption()
Request the interruption of the thread. That request is advisory and it is up to code running on the thread to decide if and how it should act upon such request. This function does not stop any event loop running on the thread and does not terminate it in any way.

Is it acceptable and safe to pthread_join myself?

I've got a setup something a bit like this:
void* work(void*) { while (true) {/*do work*/} return 0;}
class WorkDoer
{
private:
pthread_t id;
public:
WorkDoer() { pthread_create(&id, NULL, work, (void*)this); }
void Shutdown() { pthread_join(id, NULL); /*other cleanup*/ }
}
There's some cases where Shutdown() is called from the main thread, and some other cases where I want to call shutdown from within the thread itself (returning from that thread right after).
The documentation for pthread_join() says that it will return a EDEADLK if the calling thread is the same as the one passed.
My question is: Is that an okay thing to do, and if so is it safe? (thus ignoring the join fail, because I'll be nicely ending the thread in a moment anyways?) Or, is it something that should be avoided?
You can certainly call pthread_join() from the running thread itself, and as you have found out the call itself will handle it properly giving you an error code. However, there are a few problems:
It doesn't make any sense because the join won't join anything. It will merely tell you that you are doing something wrong.
The thread itself won't exit upon calling pthread_join() on itself.
Even if the thread exists, its state won't be cleaned up properly. Some other thread (i.e. your application's main thread) should call pthread_join() unless the thread was created as “detached”.
So in other words this approach is as acceptable as a bug in your program.
As a solution I would recommend to revisit the design and make sure that Shutdown() is called from the right place and at the right time. After all, the name “shutdown” doesn't make a lot of sense here because it doesn't shutdown a thing. What it does is merely waiting for a thread to finish and cleans up its state after that happens.
When you want to end the worker thread, either return from the thread routine or call pthread_exit(). Then make sure that whoever started a thread cleans things up by calling pthread_join().
If you want to force the thread to stop, consider using pthread_kill() to signal a thread or, alternatively, implement some sort of message passing that you can use to "tell" thread to stop doing whatever it is doing.
The pthread_join() function may fail if:
EDEADLK
A deadlock was detected or the value of thread specifies the
calling thread.
I would say use at your own risk.
Why not just let the thread call pthread_detach(pthread_self()); and then exit. No need to call pthread_join() then anymore and risking to have it fail.