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!
Related
I have a single-thread gui application and I do not choose a type of connection, so according to documentation the connection will be a direct one. According to documentation then: "The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread."
For my understanding, this obviously leads to the conclusion that if I disconnect such an auto-connection in a method, then there is a guarantee that there is no possibility that after completion of this method (in which I do the disconnection) I can get a slot (corresponding to the just-disconnected connection) still being called. The reason of that is, as far as I understand, the fact that no event queue is used for such an auto (here direct) connection.
Am I right? Or should I be careful and better keep a state-variable and double check this state and return from the slot if it's in a some (unclear to me) way still got called? I am especially worried for the situations where I have connections, in which signals are produced by Qt entities (e.g. signals QNetworkReply::finished(), etc.), rather than by me, as I do not control them fully.
I have found related questions, like this one, but I have not found the exact question, and so I have inconfidence and decided to ask.
If you use only direct connections then you can't "receive" any further signals after you disconnected from getting them. Direct connection is just a callback call, nothing more.
From Qt documentation on Performance Considerations And Suggestions I got the following:
use asynchronous, event-driven programming wherever possible
I'm not sure what that means, so would like to ask. Does it mean I should use signal/slots whenever possible (because they are asynchronous?)?
Qt signals/slots are not necessarily asynchronous. From https://doc.qt.io/qt-5/threads-qobject.html:
Direct Connection: The slot is invoked immediately, when the signal is emitted. The slot is executed in the emitter's thread, which is not necessarily the receiver's thread.
Queued Connection: The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Blocking Queued Connection: The slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns.
A signal subscribed to by a slot with a Direct Connection will be essentially a method call that you can "hook up" at runtime.
Also, yes, you should probably use "asynchronous, event-driven programming" "whenever possible" for a sane definition of "whenever possible".
Obviously, don't replace all method calls between your objects with signals and slots. And when you do use signals and slots, don't always make them asynchronous (Queued) - sometimes you will want the objects subscribed to your signals to finish their "reactions" to your signals before the emitting function proceeds.
In general, when you don't really care if the subscribers of your signals get their slots invoked immedtiatelly or later, just connect them up without specifying a connection type, and Qt will use Auto Connection, which will do the right thing (thread-wise). When you do care, just specify the type of connection you want.
If you feel confused by this at first, a reasonable thing to do might also be to make all connections Queued by default - you won't really notice any performance difference, and this might prevent you from accidentally writing code that depends on the slots executing "directly", when that was not your intent.
The suggestion in your link is mainly meant for any events that get generated on your main thread, most likely by UI elements - buttons, etc. The main idea is that you want to process any input events as quickly as possible, to keep the main thread free for accepting any later events and rendering your UI, and, if the events cause any significant work to be done, move that work to another thread, and have your main thread wait for a completion signal, so that your main thread remains "responsive". If you want your UI to immedtially react to any events, for example, by initiating a "loading spinner" or displaying a progress bar, you can, of course, do that directly. This, of course, also applies to any other threads that might need to remain responsive and handle other events while a larger calculation is happening in the background.
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.
Is it safe to call widget's signal function from multiple threads simultaneously? Will Qt use some kind of internal mutex to provide security of its own data structures when multiple threads call some widget's signal simultaneously?
As i understand, it is safe and N simultaneous calls of a signal function will lead to N sequential calls of a connected signal.
Am i correct?
P.S.
The threads that call a signal function are created with boost. I think, this is not important for this question. I cannot use another threads, because that threads are not related to GUI only, but they serve many parts of a program.
To be concise about this, you don't call a signal, you emit a signal. Then Qt internally handles the firing of any slots that the signal is connected to.
Emitting a signal and having it firing slot(s) may or may not be thread safe depending on the connection type.
Read here for more information.
And I think that the thread being created by boost will be a problem - the signal/slot mechanism relies on the infrastructure of QThread and QObject. It may be better and simpler if you can use QThread rather than a boost thread.
If you would be using QThreads, there would be no problem at all, as Qt manages such a situation automatically. So you (possible) problem arises from using boost threads.
However, there is a simple solution: make sure you connect the signals and slots using Qt::QueuedConnection. This will post an event into the Widget's thread's event loop and execute the slot in that thread. (this is what using QThreads does automatically when objects live in different threads).
Note that slot execution will be asynchronous in that case. If you need synchronous execution of slots (i.e. all slots must be finished before the code emitting the signal continues), use Qt::BlockingQueuedConnection
It depends on the connection. If the connection is direct, the emitting thread will be used to deliver the signal to connected slot. Is this safe? That depends on the slot. In particular, slots on QWidget cannot handle this. If the connection is queued, the signal is stored. The receiver object has an associated QThread, that thread has an event loop, and that event loop will deliver the stored signal to the receiver.
Your question describes the behavior of a queued connection. That's a valid possibility. The Qt event loop is thread safe. Both delivering signals to it, and calling slots from it are properly protected. Since there's only one QThread per receiver, that means queued signals are delivered sequentially.
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.