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..
Related
I have working on a state design pattern in C++ where I have multiple states. Some states have thread routine bounded by pthread_create. Now there are cases where one state make a transition to another state and thus the thread needs to be stopeed and memory needs to be cleaned by pthread_join.
So in summary I need to stop the thread from the thread-routine itself.
How can I achieve this?
Or is there a way that when the thread-routine is completed the memory clean-up happens automatically?
PS: Problem is, when I make a state transition to another state from the thread routine current state destructor is called. Inside the destructor of the current state I need to stop and join the thread. Otherwise there is a memory leak happening.
So in summary I need to stop the thread from the thread-routine itself. How can I achieve this?
Return from the function that is being executed at the bottom of the thread.
memory needs to be cleaned
You can clean up the thread after it has terminated by joining it from another thread. You can avoid doing that by detaching the thread before terminating it.
P.S. Prefer using the portable std::thread (or std::jthread) instead of system specific threading API.
can u add share code how to terminate a thread from the routine itself using std::thread
Example:
auto thread_fun = [] {
return; // this terminates the thread
};
std::thread t(thread_fun);
t.join(); // this waits for the thread to end, and cleans it up
I have tried searching many ways for the solution, but couldn't find proper one, so far.
I am using detached thread because I don't want my main thread to wait/block for the new child thread as it has many other important things to do.
I create a thread as follows:
std::thread rsync_t(&PreCompile::RunPreCompileThr, obj, arg1, arg2);
rsync_t.detach();
Now, Objective is to periodically check if this detached thread is active and running.
I tried future/promise and async way to do this, but it requires .get() which is something similar to join(), which I don't want.
Any suggestions to do this?
Thanks in advance.
Once you detach a thread, then you have explicitly said "I don't need to wait for this thread to finish". This is usually because the thread never finishes, and keeps running until the end of the program.
In any case, std::thread doesn't provide a mechanism to poll to see if a thread has finished without waiting. To do that you would need to use an alternative mechanism, whether the thread is detached or not.
One option is to start the thread with std::async(std::launch::async, func) and use the returned future to check if the thread is still running.
auto future=std::async(std::launch::async,thread_func);
bool thread_is_still_running=future.wait_for(std::chrono::seconds(0))!=std::future_status::ready;
If you use this option then you will need to keep the future object around (e.g. by storing it in a long-lived std::vector or a global variable), as its destructor will wait for the thread to finish.
Alternatively you can use a std::mutex and a boolean flag, or a std::atomic<bool> which is set from within the thread just before it exits, to indicate when the thread is done.
std::atomic<bool> done=false;
void thread_func(){
do_stuff();
done=true;
}
With std::async, you have an option to retrieve task status from the future. It is not necessary to use get().
https://en.cppreference.com/w/cpp/thread/future/wait_for
auto status = future.wait_for(std::chrono::milliseconds(1));
if (status == std::future_status::ready) {
// Thread has finished
}
If you detach a std::thread, you lose the communication channel that the std::thread object provides:
https://en.cppreference.com/w/cpp/thread/thread/detach
After calling detach *this no longer owns any thread.
If you want to communicate with the detached thread afterwards in any way, you need to do it manually. std::thread can no longer help you after detach.
I am using detached thread because I don't want my main thread to wait/block for the new child thread as it has many other important things to do.
The proper solution likely does not involve detach. You don't need to detach to have the thread run in parallel, it runs in parallel already when the std::thread constructor returns. Just keep the std::thread object alive and query through it, and only call join when the thread is actually supposed to be done/end. That said, std::thread only provides joinable which only changes after join, so it doesn't provide the information you need (that your code is "done" in some form).
I have the following class that has a std::thread as one of its member fields:
class MyClass {
private:
std::thread auxThread;
void run();
public:
~MyClass();
void start();
}
MyClass:~MyClass() {
if (auxThread.joinable())
auxThread.join();
}
void MyClass::run() {
//do stuff
}
void MyClass::start() {
auxThread = std::thread (&MyClass::run, this); //Move assignment
}
I can start the auxThread on-demand thanks to initializing it with an empty constructor and later move-assigning it to a std::thread object associated with an actual thread of execution (via the start() function), but to minimize system resource usage I'd like to join() auxThread with the main thread immediately after run() has exited i.e. when auxThread's work is done instead of in the MyClass destructor. It looks like condition_variable could be used to wake a sleeping main thread and accomplish this, but I don't want to block the main thread except (hopefully) briefly with join().
Two questions:
Is having a thread whose execution function has exited a drain on resources if it is never joined with the main thread, or is the thread and all associated resources released when the execution function exits (such that join() would presumably be unnecessary and return immediately)?
Is it possible to call join() on auxThread from the main thread in response to run() exiting without blocking the main thread?
Is having a thread whose execution function has exited a drain on resources if it is never joined with the main thread
Maybe. It depends on your implementation, but typically not.
is the thread and all associated resources released when the execution function exits
Probably, and if not, then as soon as possible by the OS. This is also implementation defined.
Is it possible to call join() on auxThread from the main thread in response to run() exiting without blocking the main thread?
Yes, but it wouldn't make any sense. The only thing that join does is block until the function being executed is done. Calling join again after run finished executing is unnecessary and basically a no-op.
Also, the "resources" from the thread are minimal. I wouldn't expect that a lot of memory would be allocated just for a single thread like yours. RAM is pretty cheap nowadays, so you shouldn't worry about that, as you are not executing 5M threads in parallel, which would make no sense on a conventional computer anyways.
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 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();
}