The Mac build of my (mainly POSIX) application spawns a child thread that calls CFRunLoopRun() to do an event loop (to get network configuration change events from MacOS).
When it's time to pack things up and go away, the main thread calls CFRunLoopStop() on the child thread's run-loop, at which point CFRunLoopRun() returns in the child thread, the child thread exits, and the main thread (which was blocking waiting for the child thread to exit) can continue.
This appears to work, but my question is: is this a safe/recommended way to do it? In particular, is calling CFRunLoopStop() from another thread liable to cause a race condition? Apple's documentation is silent on the subject, as far as I can tell.
If calling CFRunLoopStop() from the main thread is not the solution, what is a good solution? I know I could have the child thread call CFRunLoopRunInMode() and wake up every so often to check a boolean or something, but I'd prefer not to have the child thread do any polling if I can avoid it.
In the case of CFRunLoopStop - if it could only be called safely on the current run loop, then it would not be necessary to pass it a parameter indicating which run loop to stop.
The presence of the parameter is a strong indication that its ok to use it to stop run loops other than the current run loop.
In particular, is calling CFRunLoopStop() from another thread [safe]?
Here's what Run Loop Management says:
The functions in Core Foundation are generally thread-safe and can be called from any thread.
So maybe CFRunLoopStop is safe. But I do worry about their use of the word “generally”. My rule is: If Apple doesn't say it's safe, you should assume it's not.
To err on the safe side, you might consider creating a run loop source, adding that to your run loop, and signaling that source when it's time to end the thread. That same document includes an example of a custom run loop source.
Related
I am creating multiple threads in my program. On pressing Ctrl-C, a signal handler is called. Inside a signal handler, I have put exit(0) at last. The thing is that sometimes the program terminates safely but the other times, I get runtime error stating
abort() has been called
So what would be the possible solution to avoid the error?
The usual way is to set an atomic flag (like std::atomic<bool>) which is checked by all threads (including the main thread). If set, then the sub-threads exit, and the main thread starts to join the sub-threads. Then you can exit cleanly.
If you use std::thread for the threads, that's a possible reason for the crashes you have. You must join the thread before the std::thread object is destructed.
Others have mentioned having the signal-handler set a std::atomic<bool> and having all the other threads periodically check that value to know when to exit.
That approach works well as long as all of your other threads are periodically waking up anyway, at a reasonable frequency.
It's not entirely satisfactory if one or more of your threads is purely event-driven, however -- in an event-driven program, threads are only supposed to wake up when there is some work for them to do, which means that they might well be asleep for days or weeks at a time. If they are forced to wake up every (so many) milliseconds simply to poll an atomic-boolean-flag, that makes an otherwise extremely CPU-efficient program much less CPU-efficient, since now every thread is waking up at short regular intervals, 24/7/365. This can be particularly problematic if you are trying to conserve battery life, as it can prevent the CPU from going into power-saving mode.
An alternative approach that avoids polling would be this one:
On startup, have your main thread create an fd-pipe or socket-pair (by calling pipe() or socketpair())
Have your main thread (or possibly some other responsible thread) include the receiving-socket in its read-ready select() fd_set (or take a similar action for poll() or whatever wait-for-IO function that thread blocks in)
When the signal-handler is executed, have it write a byte (any byte, doesn't matter what) into the sending-socket.
That will cause the main thread's select() call to immediately return, with FD_ISSET(receivingSocket) indicating true because of the received byte
At that point, your main thread knows it is time for the process to exit, so it can start directing all of its child threads to start shutting down (via whatever mechanism is convenient; atomic booleans or pipes or something else)
After telling all the child threads to start shutting down, the main thread should then call join() on each child thread, so that it can be guaranteed that all of the child threads are actually gone before main() returns. (This is necessary because otherwise there is a risk of a race condition -- e.g. the post-main() cleanup code might occasionally free a resource while a still-executing child thread was still using it, leading to a crash)
The first thing you must accept is that threading is hard.
A "program using threading" is about as generic as a "program using memory", and your question is similar to "how do I not corrupt memory in a program using memory?"
The way you handle threading problem is to restrict how you use threads and the behavior of the threads.
If your threading system is a bunch of small operations composed into a data flow network, with an implicit guarantee that if an operation is too big it is broken down into smaller operations and/or does checkpoints with the system, then shutting down looks very different than if you have a thread that loads an external DLL that then runs it for somewhere from 1 second to 10 hours to infinite length.
Like most things in C++, solving your problem is going to be about ownership, control and (at a last resort) hacks.
Like data in C++, every thread should be owned. The owner of a thread should have significant control over that thread, and be able to tell it that the application is shutting down. The shut down mechanism should be robust and tested, and ideally connected to other mechanisms (like early-abort of speculative tasks).
The fact you are calling exit(0) is a bad sign. It implies your main thread of execution doesn't have a clean shutdown path. Start there; the interrupt handler should signal the main thread that shutdown should begin, and then your main thread should shut down gracefully. All stack frames should unwind, data should be cleaned up, etc.
Then the same kind of logic that permits that clean and fast shutdown should also be applied to your threaded off code.
Anyone telling you it is as simple as a condition variable/atomic boolean and polling is selling you a bill of goods. That will only work in simple cases if you are lucky, and determining if it works reliably is going to be quite hard.
Additional to Some programmer dude answer and related to discussion in the comment section, you need to make the flag that controls termination of your threads as atomic type.
Consider following case :
bool done = false;
void pending_thread()
{
while(!done)
{
std::this_thread::sleep(std::milliseconds(1));
}
// do something that depends on working thread results
}
void worker_thread()
{
//do something for pending thread
done = true;
}
Here worker thread can be your main thread also and done is terminating flag of your thread, but pending thread need to do something with given data by working thread, before exiting.
this example has race condition and undefined behaviour along with it, and it's really hard to find what is the actual problem int the real world.
Now the corrected version using std::automic :
std::atomic<bool> done(false);
void pending_thread()
{
while(!done.load())
{
std::this_thread::sleep(std::milliseconds(1));
}
// do something that depends on working thread results
}
void worker_thread()
{
//do something for pending thread
done = true;
}
You can exit thread without being concern of race condition or UB.
This question already has an answer here:
Qt, How to pause QThread immediately
(1 answer)
Closed 5 years ago.
I would like to know how to properly stop a QThread. I havea infinite loop in a thread, and I would like to stop it when I do a specific action :
I have tried :
if (thread->isRunning()){
worker->stop();
thread->terminate();
}
the stop() method set a value to false to go out of my infinite loop.
Furthermore, I don't really understand the difference between quit(), terminate() or wait(). Can someone explain me ?
Thanks.
A proper answer depends on how you actually use QThread and how you've implemented stop().
An intended use case in Qt assumes following model:
You create an object that will do some useful work in response to Signals
You create a `QThread` and move your object to this thread
When you send a signal to your object, it's processed in `QThread` you've created
Now you need to understand some internals of how this is actually implemented. There are several "models" of signals in Qt and in some cases when you "send a signal" you effectively simply call a "slot" function. That's a "direct" slot connection and in this case slot() will be executed in caller thread, one that raised a signal. So in order to communicate with another thread, Qt allows another kind of signals, queued connections. Instead of calling a slot(), caller leaves a message to object that owns this slot. A thread associated with this object will read this message (at some time later) & perform execution of slot() itself.
Now you can understand what's happening when you create and execute QThread. A newly created thread will execute QThread::run() that, by default, will execute QThread::exec() which is nothing, but an infinite loop that looks for messages for objects associated with thread and transfers them to slots of these objects. Calling QThread::quit() posts a termination message to this queue. When QThread::exec() will read it, it will stop further processing of events, exit infinite loop and gently terminate the thread.
Now, as you may guess, in order to receive termination message, two conditions must be met:
You should be running `QThread::exec()`
You should exit from slot that is currently running
The first one is typically violated when people subclass from QThread and override QThread::run with their own code. In most cases this is a wrong usage, but it's still very widely taught and used. In your case it seems that you're violating the second requirement: your code runs infinite loop and therefore QThread::exec() simply doesn't get a control and don't have any chance to check that it needs to exit. Drop that infinite loop of yours to recycle bin, QThread::exec() is already running such loop for you. Think how to re-write your code so it does not running infinite loops, it's always possible. Think about your program in terms of "messages-to-thread" concept. If you're checking something periodically, create a QTimer that will send messages to your object and implement a check in your slot. If you processing some large amount of data, split this data to smaller chunks and write your object so it will process one chunk at a time in response to some message. E.g. if you are processing image line-by-line, make a slot processLine(int line) and send a sequence of signals "0, 1, 2... height-1" to that slot. Note that you will also have to explicitly call QThread::quit() once done processing because event loop is infinite, it doesn't "know" when you processed all the lines of your image. Also consider using QtConcurrent for computationally-intensive tasks instead of QThread.
Now, the QThread::terminate() does stop a thread in a very different manner. It simply asks OS to kill your thread. And OS will simply abruptly stop your thread at arbitrary position in the code. Thread stack memory will be free'd, but any memory this stack pointed to won't. If a thread was owning some resource (such as file or mutex), it won't ever release it. An operation that involve writing data to memory can be stopped in the middle and leave memory block (e.g. object) incompletely filled and in invalid state. As you might guess from this description, you should never, ever call ::terminate() except for very rare cases where keeping running of thread is worse than getting memory & resource leaks.
QThread::wait() is just a convenience function that waits until QThread ceases to execute. It will work both with exit() and terminate().
You can also implement a threading system of your own subclassed from QThread and implement your own thread termination procedure. All you need to exit a thread is, essentially, just to return from QThread::run() when it becomes necessary and you can't use neither exit() nor terminate() for that purpose. Create your own synchronization primitive and use it to signal your code to return. But in most cases it's not a good idea, keep in mind that (unless you work with QEventLoop by yourself), Qt signal and slots won't be working properly in that case.
I evaluate JavaScript in my Qt application using QScriptEngine::evaluate(QString code). Let's say I evaluate a buggy piece of JavaScript which loops forever (or takes too long to wait for the result). How can I abort such an execution?
I want to control an evaluation via two buttons Run and Abort in a GUI. (But only one execution is allowed at a time.)
I thought of running the script via QtConcurrent::run, keeping the QFuture and calling cancel() when the Abort is was pressed. But the documentation says that I can't abort such executions. It seems like QFuture only cancels after the current item in the job has been processed, i.e. when reducing or filtering a collection. But for QtConcurrent::run this means that I can't use the future to abort its execution.
The other possibility I came up with was using a QThread and calling quit(), but there I have a similar problems: It only cancels the thread if / as soon as it is waiting in an event loop. But since my execution is a single function call, this is no option either.
QThread also has terminate(), but the documentation makes me worry a bit. Although my code itself doesn't involve mutexes, maybe QScriptEngine::evaluate does behind the scenes?
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.
Is there another option I am missing, maybe some asynchronous evaluation feature?
http://doc.qt.io/qt-4.8/qscriptengine.html#details
It has a few sections that address your concerns:
http://doc.qt.io/qt-4.8/qscriptengine.html#long-running-scripts
http://doc.qt.io/qt-4.8/qscriptengine.html#script-exceptions
http://doc.qt.io/qt-4.8/qscriptengine.html#abortEvaluation
http://doc.qt.io/qt-4.8/qscriptengine.html#setProcessEventsInterval
Hope that helps.
While the concurrent task itself can't be aborted "from outside", the QScriptEngine can be told (of course from another thread, like your GUI thread) to abort the execution:
QScriptEngine::abortEvaluation(const QScriptValue & result = QScriptValue())
The optional parameter is used as the "pseudo result" which is passed to the caller of evaluate().
You should either set a flag somewhere or use a special result value in abortEvaluation() to make it possible for the caller routine to detect that the execution was aborted.
Note: Using isEvaluating() you can see if an evaluation is currently running.
I have a pthread that I created and now I want that in a specific time interval the thread execute some code. But the user should also be able to cancel the thread. How can I cancel a thread and ensure that the thread is not cancelled when it execute the code?
In Java you handle this with
while(!isInterrupted)
Is there any similar solution with pthreads.
In the Question's example code you are checking some variable. This is not the normal pattern for interrupting threads in Java.
In Java, you interrupt a thread by calling the interrupt() method.
The thread then checks if it is interrupted inside IO and system calls (which can throw InterruptedException when this happens; this means a thread that is sleeping or waiting on IO can be awoken when interrupted) or by sampling the isInterrupted() flag (typically used in a condition in a loop, as in Question).
The distinction is important; checking some flag variable you've declared is only possible in loops and your own code; the Java interrupting system works for all threads and all non-CPU-blocking code without special effort on the part of the programmer.
Pthreads has the pthread_cancel() pattern which works like the Java interrupting pattern.
pthread_cancel is available for sending cancel requests:
A thread's cancellation type, determined by pthread_setcanceltype(3), may be
either asynchronous or deferred (the default for new threads). Asynchronous
cancelability means that the thread can be canceled at any time (usually
immediately, but the system does not guarantee this). Deferred cancelability
means that cancellation will be delayed until the thread next calls a function
that is a cancellation point. A list of functions that are or may be
cancellation points is provided in pthreads(7).
A thread's cancelability state, determined by pthread_setcancelstate(3), can
be enabled (the default for new threads) or disabled. If a thread has
disabled cancellation, then a cancellation request remains queued until the
thread enables cancellation. If a thread has enabled cancellation, then its
cancelability type determines when cancellation occurs.
So there are several options:
1: while value checking (works very well, but you don't have much control).
2: check the pthread_cancel manpage, it works to but with strict rules.
3: using pthread_signal, first you need to block, than signal for resume. It has the same issues as the second option.
Using pthreads cancel and signal will only work from within the thread that must be locked. So setting a variable to initiate the signal block. Unlocking can be done by any other thread.
The same can be done using mutex or semaphores (pthread_mutex, pthread_semaphore).
A site I recommend: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
There's no specific function to cancel a threadYou can use pthread_cancel to cancel the thread, as mentioned (but I would advise against it, unless you know what you're doing), and you have to set up your own timers. But the while(!isInterrupted) is pretty acceptable way of doing it.
It should basically be like this:
while(!isInterrupted)
{
// whatever you want to do
sleep(howLongYouWantToWait);
}
// clean up and exit the thread function here
and in the main thread have a global (or other, see below)
volatile bool isInterrupted = false;
and set it to true when you're done, and pthread_join if you want to wait for the thread to finish.
Instead of global, you can use a class variable, or a flag pointer passed to the thread function, or any other way, global is the simplest and the least preferable.
Of course, if you want to cancel the thread while it waits, and not to have it canceled only after it finishes the whole loop, then you need to deal with signals, and other stuff, but I think you're not looking for that.
Is the following safe?
I am new to threading and I want to delegate a time consuming process to a separate thread in my C++ program.
Using the boost libraries I have written code something like this:
thrd = new boost::thread(boost::bind(&myclass::mymethod, this, &finished_flag);
Where finished_flag is a boolean member of my class. When the thread is finished it sets the value and the main loop of my program checks for a change in that value.
I assume that this is okay because I only ever start one thread, and that thread is the only thing that changes the value (except for when it is initialised before I start the thread)
So is this okay, or am I missing something, and need to use locks and mutexes, etc
You never mentioned the type of finished_flag...
If it's a straight bool, then it might work, but it's certainly bad practice, for several reasons. First, some compilers will cache the reads of the finished_flag variable, since the compiler doesn't always pick up the fact that it's being written to by another thread. You can get around this by declaring the bool volatile, but that's taking us in the wrong direction. Even if reads and writes are happening as you'd expect, there's nothing to stop the OS scheduler from interleaving the two threads half way through a read / write. That might not be such a problem here where you have one read and one write op in separate threads, but it's a good idea to start as you mean to carry on.
If, on the other hand it's a thread-safe type, like a CEvent in MFC (or equivilent in boost) then you should be fine. This is the best approach: use thread-safe synchronization objects for inter-thread communication, even for simple flags.
Instead of using a member variable to signal that the thread is done, why not use a condition? You are already are using the boost libraries, and condition is part of the thread library.
Check it out. It allows the worker thread to 'signal' that is has finished, and the main thread can check during execution if the condition has been signaled and then do whatever it needs to do with the completed work. There are examples in the link.
As a general case I would neve make the assumption that a resource will only be modified by the thread. You might know what it is for, however someone else might not - causing no ends of grief as the main thread thinks that the work is done and tries to access data that is not correct! It might even delete it while the worker thread is still using it, and causing the app to crash. Using a condition will help this.
Looking at the thread documentation, you could also call thread.timed_join in the main thread. timed_join will wait for a specified amount for the thread to 'join' (join means that the thread has finsihed)
I don't mean to be presumptive, but it seems like the purpose of your finished_flag variable is to pause the main thread (at some point) until the thread thrd has completed.
The easiest way to do this is to use boost::thread::join
// launch the thread...
thrd = new boost::thread(boost::bind(&myclass::mymethod, this, &finished_flag);
// ... do other things maybe ...
// wait for the thread to complete
thrd.join();
If you really want to get into the details of communication between threads via shared memory, even declaring a variable volatile won't be enough, even if the compiler does use appropriate access semantics to ensure that it won't get a stale version of data after checking the flag. The CPU can issue reads and writes out of order as long (x86 usually doesn't, but PPC definitely does) and there is nothing in C++9x that allows the compiler to generate code to order memory accesses appropriately.
Herb Sutter's Effective Concurrency series has an extremely in depth look at how the C++ world intersects the multicore/multiprocessor world.
Having the thread set a flag (or signal an event) before it exits is a race condition. The thread has not necessarily returned to the OS yet, and may still be executing.
For example, consider a program that loads a dynamic library (pseudocode):
lib = loadLibrary("someLibrary");
fun = getFunction("someFunction");
fun();
unloadLibrary(lib);
And let's suppose that this library uses your thread:
void someFunction() {
volatile bool finished_flag = false;
thrd = new boost::thread(boost::bind(&myclass::mymethod, this, &finished_flag);
while(!finished_flag) { // ignore the polling loop, it's besides the point
sleep();
}
delete thrd;
}
void myclass::mymethod() {
// do stuff
finished_flag = true;
}
When myclass::mymethod() sets finished_flag to true, myclass::mymethod() hasn't returned yet. At the very least, it still has to execute a "return" instruction of some sort (if not much more: destructors, exception handler management, etc.). If the thread executing myclass::mymethod() gets pre-empted before that point, someFunction() will return to the calling program, and the calling program will unload the library. When the thread executing myclass::mymethod() gets scheduled to run again, the address containing the "return" instruction is no longer valid, and the program crashes.
The solution would be for someFunction() to call thrd->join() before returning. This would ensure that the thread has returned to the OS and is no longer executing.