QThread, signal/slots
-
After reading "your doing it wrong" concerning threads and signals/slots (subclassing QThread, not subclassing QThread, thread event loops...etc), my noodle is starting to get fried! Coming from a raw linux background using pthreads and forever loops I'm starting to get lost. So...a few questions:
-
QThread is a wrapper around the actual thread...so? I don't understand why subclassing it is a bad thing? Updating the main gui thread from this thread using a gui slot will still work even if this thread doesn't have an event loop, yes?
-
I realize if you want slots in this thread, you have to have an event loop for queued events, yes? Now, a direct event means the thread that emitted the signal is actually calling the dest slot, yes? So, this is why in auto mode a signal with different thread affinity always queues the event to the dest so it's event loop can call that slot...and a signal with the same affinity make a direct call...the signal is actually in the same thread as the slot, yes?
-
So...if you use a "worker" objects with slots you want executed in a QThread, you use movetothread to get the worker affinity assigned to the thread. Now, if you do it this way you have to have a thread event loop running, correct? And, if any slots of the worker object run forever, they will block the thread's event loop...which means no events will be processed for the thread's slots...correct???
-
So, if you had a thread slot that needed to run forever....what do you do about the thread's event loop? Is there a processEvent function for a QThread event loop? Do you abandon the whole slot thing and just subclass QThread and put this code in run()?? Do you break it up and use a timer? If you run a thread slot forever, and you have a signal from a different thread that emits the thread's quit slot...does this not get processed since the thread loop is blocked by the earlier slot??
Geez...this all seems a lot more complicated than a few pthreads!! ;-)
-
-
It is not a bad thing to subclass QThread. It's just not needed anymore and usually it's much more easy to just create a QObject based worker class and move it to the thread. You just start the thread using it's run slot, which in turn starts an event loop on the new thread.
I don't get the question behind your second paragraph. "Thread affinity" in Qt world means that each QObject (sub)class "lives" in a thread. That is either the main (GUI) thread, or some other thread created by you. In case of an auto connection, then if and only if the sender (emitter) of a signal and the receiver (slot) have the same thread affinity (= run in the same QThread) the slot is called directly. The call is scheduled via the event system otherwise.
If a slot (or other method) in a worker thread runs forever, the event loop is effectively blocked. Signals arriving in your thread from another thread, don't get delivered in this time.
You can manually run the event loop by calling "QCoreApplication::processEvents() ":/doc/qt-4.8/qcoreapplication.html#processEvents.
BUT: Running a forever loop in Qt based programs is usually a bad idea and unless you are forced to do so by some external dependency it is usually indicating some bad program design.
-
I don't think a forever loop (or another tight loop) is a bad thing per sé in a separate thread. It may just be the most efficient and/or easiest solution for a specific case. Sure, you won't receive signals, but if you don't need to, I don't see the problem.