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();
}
Related
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.
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.
Why should I using std::thread::join and then wait until this thread has ended? I thougt the purpose of multithreading is, that I start more threads paralelly.
Instead of join(), I also could call the function "normally", like foo().
So why is their join()? Isn't the only thing I need detach()?
Consider what happens here:
int value = 0;
void myWorkerFunction(){value = 1;}
int main()
{
std::thread t(myWorkerFunction);
t.detach();
std::cout << value << std::endl;
}
You now have a race condition. Your thread may or may not complete all the work it needs to do before value needs to get printed.*
Consider join to be a form of synchronization like a mutex; you must wait for the executing thread to release the mutex (finish) before you can continue.
Sometimes it makes sense to detach a thread, if say, it can just "work in the background" performing tasks that may not be mission critical.
I thougt the purpose of multithreading is, that I start more threads paralelly [sic]
You are not forced to join a thread immediately after it is created. You can create N threads, and then go off and do some other work. Only when you want to guarantee that a thread has finished do you need to join.
*This example is way oversimplified for the sake of explanation. Often thread creation happens in some other object or function outside of main. Whether to detach or not is usually pretty obvious from your design. (however we must always detach or join a std::thread before it goes out of scope)
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!
I am currently writing a multithreaded program where a thread may sometimes be created depending on certain circumstances. If this thread is created it needs to run independently of all other threads and I cannot afford to block any other threads to wait for it to join. The length of time the spawned thread runs for varies; sometimes it can take up to a few hours.
I have tried spawning the thread and putting a join in the destructor of the class which works fine, however if the code within the spawned thread finishes a long time before the destructor is called (which will be around 99% of the time) I would like the thread to kill itself freeing all its resources etc.
I looked into using detach for this, but you can't rejoin a detached thread and on the off chance the destructor is called before this thread finishes then the spawned thread will not finish and could have disastrous consequences.
Is there any possible solution that ensures the thread finishes before the class is destructed as well as allowing it to join as soon as the thread finishes its work?
I am using boost/c++11 for threading. Any help at all would be greatly appreciated.
Thanks
The thread may detach itself, releasing its resources. If the destructor sees that the thread is joinable, i.e. still running, let it join. If the thread reaches its end, self-detach. Possible race condition: is_joinable() returns true in destructor - thread detaches itself - destructor joins and fails miserably. So use a mutex guarding the thread's decease:
struct ThreadContainer
{
std::mutex threadEndMutex;
std::thread theThread;
ThreadContainer()
: theThread([=]()
{
/* do stuff */
// if the mutex is locked, the destructor is just
// about to join, so we let him.
if (threadEndMutex.try_lock())
theThread.detach();
})
{}
~ThreadContainer()
{
// if the mutex is locked, the thread is just about
// to detach itself, so no need to join.
// if we got the mutex but the thread is not joinable,
// it has detached itself already.
if (threadEndMutex.try_lock() && theThread.is_joinable())
theThread.join();
}
};
PS:
you might not even need the call to is_joinable, because if the thread detached itself, it never unlocked the mutex and try_lock fails.
PPS:
instead of the mutex, you may use std::atomic_flag:
struct ThreadContainer
{
std::atmoic_flag threadEnded;
std::thread theThread;
ThreadContainer()
: threadEnded(ATOMIC_FLAG_INIT)
, theThread([=]()
{
/* do stuff */
if (!threadEnded.test_and_set())
theThread.detach();
})
{}
~ThreadContainer()
{
if (!threadEnded.test_and_set())
theThread.join();
}
};
You could define pauses/steps in your "independent" thread algorithm, and at each step you look at a global variable that helps you decide to cancel calculation and auto destroy, or to continue the calculation in your thread.
If global variable is not sufficient, i.e. if a more precise granularity is needed you should define a functor object for your thread function, this functor having a method kill(). You keep references of the functors after you have launched them as threads. And when you call the MyThreadFunctor::kill() it's sets a boolean field and this field is checked at each steps of your calculation in the functor thread-function itself..