When should moveToThread be preferred over subclassing QThread?
This link shows that both methods work. On what basis should I decide what to use from those two?
I would focus on the differences between the two methods. There isn't a general answer that fits all use cases, so it's good to understand exactly what they are to choose the best that fits your case.
Using moveToThread()
moveToThread() is used to control the object's thread affinity, which basically means setting the thread (or better the Qt event loop) from which the object will emit signals and its slots will be executed.
As shown in the documentation you linked, this can be used to run code on a different thread, basically creating a dummy worker, writing the code to run in a public slot (in the example the doWork() slot) and then using moveToThread to move it to a different event loop.
Then, a signal connected to that slot is fired. Since the object that emits the signal (the Controller in the example) lives in a different thread, and the signal is connected to our doWork method with a queued connection, the doWork method will be executed in the worker thread.
The key here is that you are creating a new event loop, run by the worker thread. Hence, once the doWork slot has started, the whole event loop will be busy until it exits, and this means that incoming signals will be queued.
Subclassing QThread()
The other method described in Qt's documentation is subclassing QThread. In this case, one overrides the default implementation of the QThread::run() method, which creates an event loop, to run something else.
There's nothing wrong with this approach itself, although there are several catches.
First of all, it is very easy to write unsafe code, because the run() method is the only one in that class that will be actually run on another thread.
If as an example, you have a member variable that you initialize in the constructor and then use in the run() method, your member is initialized in the thread of the caller and then used in the new thread.
Same story for any public method that could be called either from the caller or inside run().
Also slots would be executed from the caller's thread, (unless you do something really weird as moveToThread(this)) leading to extra confusion.
So, it is possible, but you really are on your own with this approach and you must pay extra attention.
Other approaches
There are of course alternatives to both approaches, depending on what you need. If you just need to run some code in background while your GUI thread is running you may consider using QtConcurrent::run().
However, keep in mind that QtConcurrent will use the global QThreadPool. If the whole pool is busy (meaning there aren't available threads in the pool), your code will not run immediately.
Another alternative, if you are at the least on C++11, is to use a lower level API such as std::thread.
As a starting point: use neither. In most cases, you have a unit of work that you wish to run asynchronously. Use QtConcurrent::run for that.
If you have an object that reacts to events and/or uses timers, it's a QObject that should be non-blocking and go in a thread, perhaps shared with other objects.
Such an object can also wrap blocking APIs.
Subclassing QThread is never necessary in practice. It's like subclassing QFile. QThread is a thread handle. It wraps a system resource. Overloading it is a bit silly.
Simple answer is ALWAYS.
When you move object to thread:
it is easy to write test for code
it is easy to refactor code (you can use thread but you don't have to).
you do not mix functionality of thread with business logic
there is no problem with object lifetime
When you subclass QThread
it is harder to write test
object clean up process can get very confusing leading to strange errors.
There is full description of the problem from Qt blog: You’re doing it wrong….
QtConcurrent::run is also very handy.
Please remember that by default slots are trying to jump between treads when signal is send from other thread object is assigned to. For details see documentation of Qt::ConnectionType.
QThread is low level thread abstraction, first look at high level API QtConcurrent module and QRunnable
If nothing of these is suitable for you, then read this old article, it tells how you should use QThread. Think about thread and task performed in this thread as a separate objects, don't mix them together.
So, if you need to write come custom, specific or extended thread wrapper then you should subclass QThread.
If you have QObject derived class with signals and slots, then use moveToThread on it.
In other cases use QtConcurrent, QRunnable and QThreadPoll.
Related
We are trying to write a portable shared library that makes use of some Qt classes for convenience (mainly QTimer and QTcpSocket); no GUI stuff, though. The according signal/slot connections appear to require some Qt event loop, so we "prime" a QCoreApplication as outlined in this answer. Accordingly, we set up a worker object that does the heavy lifting and move it to a QThread.
The problem we run into now is that the queued connections between the QThread's owner object (within the main thread) and the worker object within the QThread seem to never get handled on Linux systems, at least as long as the program that implements our library does not provide any further Qt event loop of its own in the main thread. This is not very helpful, since the data passed from the worker to the main thread should be passed further using some callback functions, which now never get called, though.
My question is thus: is there a way to get an event loop to work in the library main thread without locking it or the host program up (which seems to be the case when just putting a QCoreApplication::exec() or similar there)? Or will we have to set up a different inter-thread communication scheme (independent from Qt) in order to deal with these data transfers?
Since we do not know if the host software is going to run on a QApplication or not, ideally I'd also have a check for that before setting up a main thread event loop. Is a simple if(qApp != nullptr) enough for that?
P.S.: A few things I tried but which did not work for me, either:
Settings up a QEventLoop in a std::thread launched from the main thread (probably not working because still not in the main thread)
Setting up a QEventLoop in the main thread class and triggering its processEvents() function periodically using a QTimer (probably not working due to the missing event loop for the QTimer::timeout signal in the main function)
Starting the QCoreApplication in a std::thread (gives a run-time warning on Windows that QCoreApplication should be started in the main thread)
In Qt parlance, a callback is called Qt::DirectConnection. But of course those callbacks will run on your worker thread. But that’d be the case with any other library that uses callbacks, so Qt is not a problem here, and neither is your code: the basic idea has this property.
If the host application is not using an event loop (any event loop, not necessarily Qt’s), then there’s nothing you can do other than polling – see below.
If the host application runs an X11 event loop, then you need to ensure that your copy of Qt is using the same underlying event loop as the host application. Usually, this would be the glib’s event loop, and then it should work automagically. Otherwise, you’ll need to pass to the user the file descriptor of the synchronization primitive used by Qt’s event loop, and the user will need to integrate it into their event loop. You’ll face the same problem whether you use Qt or not: rolling your own communication method won’t fix it, since you still need a waitable primitive that will interoperate with whatever event loop the user is using.
The user can of course poll for callbacks whenever they feel like it: expose a mainPoll() method that forwards to QCoreApplication::processEvents().
Despite accepting another answer (which I deem more correct), I'd still like to mention a workaround that worked surprisingly well: We actually managed to get around the event loop/thread problems on most systems by connecting the worker thread signals with lambda functions in constructor of the class that sets up the worker.
Now, I doubt that this behaviour is properly thread-safe, and having relatively lengthy lambda functions declared in connect function calls is certainly not good style. But in case anyone else ends up struggling with this issue, this may be a short-term solution or (temporary) workaround.
Actually I have been using signals and slots while programing in Qt.
The main use of signals and slots are in the UI interaction, for example a clicked button sends a signal that will invoke a slot to perform action.
I know that it's possible to use signals and slots for non-gui application, for example a server side application.
I looked for other libraries that offers signal and slots and I found boost library. It's some how different from what I learned from Qt.
And then I was wondering what's the real utility of signals and slots, since I can manually call a function to perform an action at a given time.
for example in boost here is an example of signals/slots :
#include <boost/signals2.hpp>
#include <iostream>
void mySlot(){
std::cout << "I'm a slot" << std::endl;
}
void main(){
boost::signals2::signal<void ()> sig;
// Connecting the slot to the signal.
sig.connect(mySlot);
// Emitting a signal that will call mySlot
sig();
return 0;
}
I could simply do the same thing with a simple call of mySlot() isn't it ?
Not that what made me think is that when we try to connect two different slots, they are called in the same order than connection. and if the first slot is blocking ( try to add an infinite loop) the second slots will never be called ! I guess that it's a kind of vector that stores the addresses of the functions and then iterate the loop and call one by one !
What's the magic behind the signals and slots ? or it's only a kind of abstraction for the developer ?
Thank you in advance.
In short: The main idea is decoupling in my opinion.
In longer: With direct function calls, you could not have a well-separate establishment between the common functionality and the clients of it, for instance. There would be a tight coupling unlike with signals and slots because you would need to know at the point of some condition meeting your criteria which methods exactly to call.
If you would like to gain more freedom, like with many other OOP design patterns, you need something like signals and slots. When a common component, let us call it a library, emits a signal, it does not have to be aware of the (potentially not-yet-existing) client interfaces. This makes the common component flexible enough.
It will also keep responsiveness of the application better since it is not a direct call, but processed by the Qt event loop. Arguably, you could circumvent this with custom threading mechanisms, but that would be lotta more work to make it safe enough, and you would end up doing something close this in the end of the day.
Signals and slots are simply a communication mechanism that can be used across different threads of execution. That is the main value (especially in a GUI focussed library such as QT). Usually there is 1 thread responsible for drawing and managing the graphical side of the application and 1 or more worker threads. Using signals and slots it is possible to abstract away from this. If you wanted to use direct function calls you'd need to synchronise the threads which would lead to reduced performance and responsiveness on the GUI side.
Indeed within one execution thread it does not make much sense using signals and slots. The value comes in when you want to communicatie between processes (on the same machine or between different machines).
I have a UI program in which i used QFuture to run a function in a different class that was heavy on processor etc. and caused my UI to crash, after using QFuture to thread this out it works fine, however I have another function that will need to be called right after however this one is within the same class as where I'm calling it from.
I have used the same code to do the second one but it just shows errors about Timers which I'm not even using, also I don't know if its right that I'm using this in the arguments:
future = new QFuture<void>;
*future = QtConcurrent::run(this, &GUI::test);
test being a local function, is it something to do with the fact that I can't have two concurrent::run calls or something, I've tried looking at the documentation which hasn't helped unfortunately
basically when this is called the UI locks up and I get some strange warnings, and I thought the point of threading it was that the UI wouldn't crash
Here's my best guess on this.
I'm guessing that you have the following situation. (Note: understanding the situation you're in is very useful when trying to come up with a solution for a problem. Often it turns out that the OP is going about something in a fundamentally wrong way and should be doing something entirely different.)
You have a GUI. You have an operation that takes a long time, which you want to run in a worker thread. And at the end of the long operation, you need to call a function on the GUI thread, probably to update the GUI or something similar.
So you launch the background task using QtConcurrent::run(&someObject, &SomeObject::task). Then you need some way to be notified, on the GUI thread, when the task is completed.
The correct way to do this is to attach a QtFutureWatcher to the future returned from run() and connect a slot on your GUI class to its finished signal. Qt's signal mechanism will ensure that the slot is called on the right thread.
I'm having trouble with Qt signals.
I don't understand how DirectConnection and QueuedConnection works?
I'd be thankful if someone will explain when to use which of these (sample code would be appreciated).
You won't see much of a difference unless you're working with objects having different thread affinities. Let's say you have QObjects A and B and they're both attached to different threads. A has a signal called somethingChanged() and B has a slot called handleChange().
If you use a direct connection
connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection );
the method handleChange() will actually run in the A's thread. Basically, it's as if emitting the signal calls the slot method "directly". If B::handleChange() isn't thread-safe, this can cause some (difficult to locate) bugs. At the very least, you're missing out on the benefits of the extra thread.
If you change the connection method to Qt::QueuedConnection (or, in this case, let Qt decide which method to use), things get more interesting. Assuming B's thread is running an event loop, emitting the signal will post an event to B's event loop. The event loop queues the event, and eventually invokes the slot method whenever control returns to it (it being the event loop). This makes it pretty easy to deal with communication between/among threads in Qt (again, assuming your threads are running their own local event loops). You don't have to worry about locks, etc. because the event loop serializes the slot invocations.
Note: If you don't know how to change a QObject's thread affinity, look into QObject::moveToThread. That should get you started.
Edit
I should clarify my opening sentence. It does make a difference if you specify a queued connection - even for two objects on the same thread. The event is still posted to the thread's event loop. So, the method call is still asynchronous, meaning it can be delayed in unpredictable ways (depending on any other events the loop may need to process). However, if you don't specify a connection method, the direct method is automatically used for connections between objects on the same thread (at least it is in Qt 4.8).
in addition to Jacob Robbins answer:
the statement "You won't see much of a difference unless you're working with objects having different thread affinities" is wrong;
emitting a signal to a direct connection within the same thread will execute the slot immediately, just like a simple function call.
emitting a signal to a queued connection within the same thread will enqueue the call into the threads event loop, thus the execution will always happen delayed.
QObject based class has a queued connection to itself
Jacob's answer is awesome. I'd just like to add a comparative example to Embedded Programming.
Coming from an embedded RTOS/ISR background, it was helpful to see the similarities in Qt's DirectConnection to Preemptive behavior of the ISRs and Qt's QueuedConnection to Queued Messages in an RTOS between tasks.
Side note: Coming from an Embedded background, it's difficult for me to not define the behavior in the programming. I never leave the argument as Auto, but that is just a personal opinion. I prefer everything to be explicitly written, and yes that gets difficult at times!
If there are two slots in two different threads and these slots are connected to a signal in a third thread. Can it happen, that both slots get called at the same time by the signal or do they get called synchronized every time?
I ask because i want to send some callback data structure (encapsulated with QSharedPointer) and ask if locking mechanism inside is needed.
You don't need to lock the actual signal/slot calls if you're using a Qt::QueuedConnection to pass the information to your threads, as the QueuedConnection mechanism handles this in a thread-safe manner.
That being said, you still need to protect any shared memory your threads access, regardless of how they were called. The fact that a third thread emitted a single signal to cause both slots to be called will not change this.
Have a look here (official Qt documentation for Qt's signal/slot mechanism regarding threads).
Each slot is called inside its thread, therefore I am pretty sure anything can happen. You should install a lock mechanism.