How to gracefully quit a multi-threaded application? - c++

If I have a Qt application (that uses QCoreApplication), and this application starts a few permanent threads, what is the proper way to shut down the application?
Is it alright to just run QCoreApplication::quit() in one of the threads? Will this cause the other threads to be gracefully terminated (and have all their contained objects' destructors called, as opposed to being forcefully killed)?
Further details to explain the nature of the threads: they are predefined and run from startup and do not stop until the application exits, i.e. they're permanent. They run their own event loop and communicate with other threads via signals and slots. These are normal threading, not task-based concurrency.

Most long running 'thread main' functions have a form a bit like the following:
while (doWork) {
work();
}
with doWork being a std::atomic<bool>.
When the main thread wants to quit, it sets myThread.doWork = false on all the threads that are still alive, which allows them to fall out when they're ready.
By calling myThread.wait() on the main thread, it blocks until the thread that you've told to stop doing work actually stops.
In doing this for all your threads, by the time the main thread leaves main() it's the only thread still running.
Side note:
if you have to await work to be pushed to it, you probably want to look into the QWaitCondition class so that you can awake your thread both when there's work and when you want it to stop.

It highly depends on how you use the threads.
If you use them as seperate eventloops, and not as "worker threads", simply stop the by quitting the threads from the QCoreApplication::aboutToQuit signal:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->quit();
thread->wait(1000);
});
(For multiple threads, first quit all of them and then wait)
In case you use them as real workerthreads, where you do permanent work in a loop etc, you can use QThreads interruptions mechanism. In your thread do:
while(!QThread::currentThread()->isInterruptionRequested()) {
// code...
}
and quit them in a very similar way:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->requestInterruption();
thread->wait(1000);
});

Most modern platforms will aim to 'clean up' after processes end abruptly.
That is end all the threads, recover all the memory, close any open files and recover any other resources or handles allocated to a process.
But it not recommended that is relied on and when execution may have 'durable' side-effects such as writing to files or communicating with other processes (including sharing memory) that may survive termination it may not be possible to clean up easily. Files could remain half written and other processes may receive half complete messages or send messages to processes that didn't declare termination.
It's also very hard to identify memory leaks in processes that are ended abruptly.
Best practice is always going to bring all threads to a known conclusion.
The recommended way to terminate is to define one or more stop flags (often bool) that will be checked by threads at 'safe' points to terminate.
Those stop flags should be atomic (std::atomic<>) or protected by a std::mutex if used in a wait() condition.
In that model termination code could look something like..
#include <iostream>
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>
std::atomic<bool> stop_flag;
std::vector<std::thread> threads;
std::mutex cout_mutex;//std::cout is not natively synchronized.
void chug(size_t index){
int i{0};
while(!stop_flag){
{
std::lock_guard<std::mutex> guard{cout_mutex};
std::cout<<index<<" : "<<i<<std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));//slow it down!
++i;
}
}
//stop_all brings all the threads to a safe and known conclusion.
void stop_all(){
stop_flag=true;
for( auto& curr: threads){
curr.join();
}
}
int main() {
const size_t num{10};
for(size_t i=0;i<num;++i){
threads.emplace_back(chug,i);
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));//Let it run!
stop_all();
return 0;
}

With the author of question explanation we can narrow down to exact type of threads:
I have predefined threads that run from startup and do not stop until
the application exits, i.e. they're permanent. They run their own
event loop and communicate with other threads via signals and slots.
These are normal threading, not task-based concurrency. How can I
organize this type of multi-threading?
It is quite easy to organize in Qt by "moving" the object with predefined signals and slots to the thread in which its methods supposed to run in.
class Worker : public QObject
{
Q_OBJECT
public:
Worker(Load*);
signals:
void produce(Result*);
public slots:
void doWork(Load*);
};
void Worker::doWork(Load* pLoad)
{
// here we can check if thread interruption is requested
// if the work is of iterative long time type
while(!QThread::currentThread()->isInterruptionRequested())
{
process(pLoad);
if (pLoad->finished())
{
emit produce(pLoad->result()); // deliver the result
return; // back to worker thread event loop to wait
}
}
// interrupted before the load finished
QThread::currentThread()->quit();
}
// { somewhere on the main thread
// main thread launches worker threads like this one
QThread thread;
Worker worker(new Load());
worker.moveToThread(&thread); // the worker will be leaving in the thread
// start!
thread.start();
// worker thread adds new workload on its thread
// through the thread event loop by invokeMethod
QMetaObject::invokeMethod(&worker, "doWork", Qt::AutoConnection,
Q_ARG(Load*, new Load));
// after all we want to quit the app
thread.requestInterruption(); // for faster finishing
// or
thread.quit(); // for finishing after the last data processed
thread.wait(); // for one thread wait but you can catch finished()
// signals from many threads (say, count until all signaled)
// ........
// quit the app
// ........
qApp->quit();
// } somewhere on main thread
It may look a bit like task-based concurrency but there is no task object on thread picking up its load from the queue. It just demonstrates Qt work thread communicating via signals and slots.

I agree #UKMonkey idea for a thread block but if some threads are waiting for a device or a memory and condition waits that dose not guaranteed thread quit and even it's prevent application quit.
so what to do for those situations , QCoreApplication has aboutToQuit() signal you can connect it to a slot and force your threads to quit and check if a thread don't quit gracefully and correct it's quit scenario.

Related

Correct usage of std::condition_variable to trigger timed execution

I am trying to execute a piece of code in fixed time intervals. I have something based on naked pthread and now I want to do the same using std::thread.
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
bool running;
std::mutex mutex;
std::condition_variable cond;
void timer(){
while(running) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::lock_guard<std::mutex> guard(mutex);
cond.notify_one();
}
cond.notify_one();
}
void worker(){
while(running){
std::unique_lock<std::mutex> mlock(mutex);
cond.wait(mlock);
std::cout << "Hello World" << std::endl;
//... do something that takes a variable amount of time ...//
}
}
int main(){
running = true;
auto t_work = std::thread(worker);
auto t_time = std::thread(timer);
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
running = false;
t_time.join();
t_work.join();
}
The worker in reality does something that takes a variable amount of time, but it should be scheduled at fixed intervals. It seems to work, but I am pretty new to this, so some things arent clear to me...
Why do I need a mutex at all? I do not really use a condition, but whenever the timer sends a signal, the worker should do its job.
Does the timer really need to call cond.notify_one() again after the loop? This was taken from the older code and iirc the reasoning is to prevent the worker to wait forever, in case the timer finishes while the worker is still waiting.
Do I need the running flag, or is there a nicer way to break out of the loops?
PS: I know that there are other ways to ensure a fixed time interval, and I know that there are some problems with my current approach (eg if worker needs more time than the interval used by the timer). However, I would like to first understand that piece of code, before changing it too much.
Why do I need a mutex at all? I do not really use a condition, but whenever the timer sends a signal, the worker should do its job.
The reason you need a mutex is that the thread waiting for the condition to be satisfied could be subject to a spurious wakeup. To make sure your thread actually received the notification that the condition is correctly satisfied you need to check that and should do so with a lambda inside the wait call. And to guarantee that the variable is not modified after the spurious wakeup but before you check the variable you need to acquire a mutex such that your thread is the only one that can modify the condition. In your case that means you need to add a means for the worker thread to actually verify that the timer did run out.
Does the timer really need to call cond.notify_one() again after the loop? This was taken from the older code and iirc the reasoning is to prevent the worker to wait forever, in case the timer finishes while the worker is still waiting.
If you dont call notify after the loop the worker thread will wait indefinitely. So to cleanly exit your program you should actually call notify_all() to make sure every thread waiting for the condition variable wakes up and can terminate cleanly.
Do I need the running flag, or is there a nicer way to break out of the loops?
A running flag is the cleanest way to accomplish what you want.
Let's first check the background concepts.
Critical Section
First of all Mutex is needed to mutually exclude access to a critical section. Usually, critical section is considered to be shared resource. E.g. a Queue, Some I/O (e.g. socket) etc. In plain words Mutex is used to guard shared resource agains a Race Condition, which can bring a resource into undefined state.
Example: Producer / Consumer Problem
A queue should contain some work items to be done. There might be multiple threads which put some work items into the Queue (i.e. produce items => Producer Threads) and multiple threads which consume these items and do smth. useful with them (=> Consumer Threads).
Put and Consume operations modify the Queue (especially its storage and internal representations). Thus when running either put or consume operations we want to exclude other operations from doing the same. This is where Mutex comes into play. In a very basic constellation only one thread (no matter producer or consumer) can get access to the Mutex, i.e. lock it. There exist some other Higher Level locking primitives to increase throughput dependent on usage scenarios (e.g. ReaderWriter Locks)
Concept of Condition Variables
condition_variable::notify_one wakes up one currently waiting thread. At least one thread has to wait on this variable:
If no threads are waiting on this variable posted event will be lost.
If there was a waiting thread it will wake up and start running as soon as it can lock the mutex associated with the condition variable. So if the thread which initiated the notify_one or notify_all call does not give up the mutex lock (e.g. mutex::unlock() or condition_variable::wait()) woken up thread(s) will not run.
In the timer() thread mutex is unlocked after notify_one() call, because the scope ends and guard object is destroyed (destructor calls implicitly mutex::unlock())
Problems with this approach
Cancellation and Variable Caching
Compilers are allowed to cache values of the variables. Thus setting running to true might not work, as the values of the variable might be cached. To avoid that, you need to declare running as volatile or std::atomic<bool>.
worker Thread
You point out that worker needs to run in some time intervals and it might run for various amounts of time. The timer thread can only run after worker thread finished. Why do you need another thread at that point to measure time? These two threads always run as one linear chunk and have no critical section! Why not just put after the task execution the desired sleep call and start running as soon as time elapsed? As it turns out only std::cout is a shared resource. But currently it is used from one thread. Otherwise, you'd need a mutex (without condition variable) to guard writes to cout only.
#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>
std::atomic_bool running = false;
void worker(){
while(running){
auto start_point = std::chrono::system_clock::now();
std::cout << "Hello World" << std::endl;
//... do something that takes a variable amount of time ...//
std::this_thread::sleep_until(start_point+std::chrono::milliseconds(1000));
}
}
int main(){
running = true;
auto t_work = std::thread(worker);
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
running = false;
t_work.join();
}
Note: With sleep_until call in the worker thread the execution is blocked if your task was blocking longer than 1000ms from the start_point.

Is there a reliable way to force a thread to stop in C++? (especially detached ones)

I am recently working with threads in C++11. now I am thinking about how to force stop a thread. I couldn't find it on stackoverflow, and also tried these.
One variable each thread : not so reliable
return in the main thread : I have to force quit only one not all
and I have no more ideas. I have heard about WinAPI, but I want a portable solution. (that also means I wont use fork())
Can you please give me a solution of this? I really want to do it.
One of the biggest problems with force closing a thread in C++ is the RAII violation.
When a function (and subsequently, a thread), gracefully finishes, everything it held is gracefully cleaned up by the destructors of the objects the functions/threads created.
Memory gets freed,
OS resources (handles, file descriptors etc.) are closed and returned to the OS
Locks are getting unlocked so other threads can use the shared resources they protect.
other important tasks are preformed (such as updating counters, logging, etc.).
If you brutally kill a thread (aka by TerminateThread on Windows, for example), non of these actually happen, and the program is left in a very dangerous state.
A (not-so) common pattern that can be used is to register a "cancellation token" on which you can monitor and gracefully shut the thread if other thread asks so (a la TPL/PPL). something like
auto cancellationToken = std::make_shared<std::atomic_bool>();
cancellationToken->store(false);
class ThreadTerminator : public std::exception{/*...*/};
std::thread thread([cancellationToken]{
try{
//... do things
if (cancellationToken->load()){
//somone asked the thred to close
throw ThreadTerminator ();
}
//do other things...
if (cancellationToken->load()){
//somone asked the thred to close
throw ThreadTerminator ();
}
//...
}catch(ThreadTerminator){
return;
}
});
Usually, one doesn't even open a new thread for a small task, it's better to think of a multi threaded application as a collection of concurrent tasks and parallel algorithms. one opens a new thread for some long ongoing background task which is usually performed in some sort of a loop (such as, accepting incoming connections).
So, anyway, the cases for asking a small task to be cancelled are rare anyway.
tldr:
Is there a reliable way to force a thread to stop in C++?
No.
Here is my approach for most of my designs:
Think of 2 kinds of Threads:
1) primary - I call main.
2) subsequent - any thread launched by main or any subsequent thread
When I launch std::thread's in C++ (or posix threads in C++):
a) I provide all subsequent threads access to a boolean "done", initialized to false. This bool can be directly passed from main (or indirectly through other mechanisms).
b) All my threads have a regular 'heartbeat', typically with a posix semaphore or std::mutex, sometimes with just a timer, and sometimes simply during normal thread operation.
Note that a 'heartbeat' is not polling.
Also note that checking a boolean is really cheap.
Thus, whenever main wants to shut down, it merely sets done to true and 'join's with the subsequent threads.
On occasion main will also signal any semaphore (prior to join) that a subsequent thread might be waiting on.
And sometimes, a subsequent thread has to let its own subsequent thread know it is time to end.
Here is an example -
main launching a subsequent thread:
std::thread* thrd =
new std::thread(&MyClass_t::threadStart, this, id);
assert(nullptr != thrd);
Note that I pass the this pointer to this launch ... within this class instance is a boolean m_done.
Main Commanding shutdown:
In main thread, of course, all I do is
m_done = true;
In a subsequent thread (and in this design, all are using the same critical section):
void threadStart(uint id) {
std::cout << id << " " << std::flush; // thread announce
do {
doOnce(id); // the critical section is in this method
}while(!m_done); // exit when done
}
And finally, at an outer scope, main invokes the join.
Perhaps the take away is - when designing a threaded system, you should also design the system shut down, not just add it on.

How to terminate or stop a detached thread in c++?

I am interested in terminating/stopping/killing a detached thread in c++. How can this be done?
void myThread()
{
int loop = 0;
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
++loop;
}
}
void testThread()
{
std::thread globalThread(myThread);
globalThread.detach();
}
int main(void)
{
testThread();
for(unsigned int i=0; i < 1000; i++)
{
cout << "i = " << i << endl;
}
return 0;
}
The reason why I'd like to "stop"/"terminate" the globalThread() is because valgrind lists that this is a "possibly lost" type of memory leak (152 bytes). What is the best way to deal with this?
There are no provisions to stop another thread; whether it's detached, or joinable.
The only way to stop a thread, is for the thread to return from the initial thread function.
In this particular case, I would suggest the following changes:
Do not detach the thread. Instantiate it in main().
Add a bool value, and a std::mutex, the bool gets initialized to false
Each time through the thread's inner loop, lock the mutex using a std::unique_lock, take the bool's value, then unlock the mutex. After unlocking the mutex, if the bool was true, break out of the loop, and return.
In main(), before exiting: lock the mutex, set the bool flag to true, unlock the mutex, then join the thread
This is not perfect, since it will take up to five seconds for the second thread to check the bool flag, and return. But, this would be the first tep.
There is no way to cleanly shutdown a detached thread. Doing so would require waiting for the cleanup to complete, and you can only do that if the thread is joinable.
Consider, for example, if the thread holds a mutex that another thread needs to acquire in order to cleanly shut down. The only way to cleanly shut down that thread would be to induce it to release that mutex. That would require the thread's cooperation.
Consider if the thread has opened a file and holds a lock on that file. Aborting the thread will leave the file locked until the process completes.
Consider if the thread holds a mutex that protects some shared state and has put that shared state temporarily into a inconsistent state. If you terminate the thread, either the mutex will never be released or the mutex will be released with the protected data in an inconsistent state. This can cause crashes.
You need a thread's cooperation to cleanly shut it down.
You could drop below the C++ Standard and use OS-specific functions, such as sending your own process a signal while setting the signal mask so it's delivered only to the detached thread - a handler can set a flag that's polled from your thread. If your main routine waits longer than the poll period plus a bit you can guess it should have terminated ;-P. The same general idea can be used with any other signalling mechanism, such as an atomic terminate-asap flag variable.
Alternatively, and only as a last resort, there's pthread_cancel and similar. Note that async cancellation like this is a famously dangerous thing to do in general - you should be careful that the thread you terminate can't be in any code with locked/taken resources or you may have deadlocks, leaks, and/or undefined behaviour. For example, your code calls std::this_thread::sleep_for(std::chrono::seconds(5)); - what if that asks the OS for a callback when the interval expires, but the function to continue to afterwards uses the terminated thread's stack? An example where it can be safe is if the thread's doing some simple number crunching in a loop within your app.
Otherwise Sam's answer documents an alternative if you avoid detaching the thread in the first place....
In noticing that the straight forward answer of "NO" is less than helpful:
Generally you will see the answer being akin to "use your own inter thread communication"
Whether that is an atomic bool being shared between the main thread and the child thread or whether that is signalling a thread with another thread via OS methods.
It may be helpful to shift the focus to the specifics of WHEN you would like a detached thread to die, rather than 'who does the killing'.
https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit
Looking at code examples like the above helped me with what I was dealing with (main thread dying obscurely and children segfaulting) and I hope it helps you.
I think the best way is to create signal handler
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler( int signum ) {
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
int main () {
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
https://www.tutorialspoint.com/cplusplus/cpp_signal_handling.htm
this is the site where I got the code. You can also use raise function to create signal in the code. Checkout the link.
You can terminate the detached thread by setting its condition to break the loop though the pointer.
You can also wait for that thread until it finishes execution using semaphore.

Making the main thread wait till all other Qthread finished

is there a way to force the main thread to wait until all threads created from it, will finish their job, before finishing the program. I mean:
int main(){
QthreadClass a; // in cons' a thread is created and running
QthreadClass b; // same as before
*** wish to wait till both created thread finished their jobs ***
return 0;
}
Well, what about:
a.wait();
b.wait();
Or, you would rather start an event loop (as usually for Qt applications) that you quit when both of your threads end (QThread emits finished() and terminated() signals).
Normally, with Qt you will have a QApplication based class with an event loop with signals and slots, that will not exit from the main function until you want to. In that case you can simply connect the QThread::finish() signal to a slot that checks if all threads are done.
Without an event loop and signals/slots, Qt threads don't have a join() method, found in other threading implementation, but QThread::wait() is somewhat similar.
bool QThread::wait(unsigned long time = ULONG_MAX)
Blocks the thread until either of these conditions is met:
The thread associated with this QThread object has finished execution (i.e. when it returns from QThread::run()). This function will return true if the thread has finished. It also returns true if the thread has not been started yet.
time milliseconds has elapsed. If time is ULONG_MAX (the default), then the wait will never timeout (the thread must return
from QThread::run()). This function will return false if the wait timed out.
Note tho that it is considered a terrible practice to block the main thread, not even with computation, much less just to wait for something. Anything over several dozen milliseconds has detrimental effect on the user experience, and higher stalls are likely to give you a "this app is not responding" msg from the OS. If you wait on a result, wait for it in another thread, and only pass it to the main thread once it is done.

Managing multiple concurrent threads

I'm writing a multi-threaded program in C++ using C++11 threading library.
I have the following requirements:
Main thread listens to some type of events, and fires off a new thread for each new event
When program termination is requested, new thread creation is blocked and we wait for the old threads to finish
I have the option to store the threads in some container, for example, a list. Before exit, all threads in the container are join()-ed. However, since STL containers are not thread-safe, additional synchronization is needed when adding a new thread and removing a finished thread from the container. The interaction between the main thread and the child threads becomes a little more complicated in this case. Should the child thread remove itself from the container? If not, how does it let the main thread know when it's time to remove? etc.
Another way I see is to have an atomic int which is incremented by the main thread when a child thread is created, and decremented by the child thread right before its termination (threads will be detach()-ed after creation, so I won't have to manage any std::thread objects). Before exiting, we just wait for the atomic integer to become 0 in a simple loop. This solution looks better to me because there are less moving parts and no locking (at least as long as the target platform has a lock-free implementation of std::atomic<int>).
So, my question is, which of the above methods would you prefer?
Using the thread counter would be my choice, combined with a condition wait. The last thread exiting should signal the condition variable to wake up the waiter.
// the waiter
{
std::lock_guard<std::mutex> g(threads_lock);
while (threads > 0) {
threads_cond.wait(threads_lock);
}
}
//...
// the threads that are exiting
if (--threads == 0) {
std::lock_guard<std::mutex> g(threads_lock);
threads_cond.notify_one();
}
This is assuming that threads is std::atomic, of course.