How can i create several thread in a queue with Qt? - c++

How can I create threads in a queue with Qt that execute step by step (when one thread completed another thread started)?
Please give me a code example?

Look at QThreadPool.
However, as Frank pointed out, if you execute things after each other, there is no need for threads.

There is a "finished()" signal from the QThread object. In your thread manager thread (i.e. your main qwidget or qmainwindow), you could have a queue manager class that has a slot to which this signal is connected. The slot would initialize and execute the next thread in the queue when it receives the finished signal from the currently running thread.
This would prevent blocking in your manager thread and allow you to execute these thread objects from a queue as you describe.
Make sure that each time you respond to a finished signal, you connect the next thread's finished signal to your queue manager slot. You also want to make sure that you start the thread in your "add to queue" method if there are no other threads currently running.

Related

Is Qt's event loop thread safe or atomic? How is it synchronised when dealing with `QueuedConnection`?

Suppose 2 QThreads are running with following relation:
connect(&Object1OfThread1, &Object1::Signal,
&Object2OfThread2, &Object2::Slot, Qt::QueuedConnection);
So when an object from one thread raises a signal, the other thread's slot is invoked. As discussed in Qt signals (QueuedConnection and DirectConnection), due to Qt::QueuedConnection, the Signal() is posted/appended into the event loop of the Thread2. When it turn comes, the Slot() is invoked.
Question: Is the event loop itself thread-safe?
viz. what if Thread1 and Thread3 both post a signal simultaneously to Thread2's event loop.
The article mentioned in this comment, says that the event queue is protected by a mutex.
How Qt Signals and Slots Work - Part 3 - Queued and Inter Thread Connections
A QueuedConnection will post an event to the event loop to eventually be handled.
When posting an event (in QCoreApplication::postEvent), the event will be pushed in a per-thread queue (QThreadData::postEventList). The event queue is protected by a mutex, so there is no race conditions when threads push events to another thread's event queue.
Once the event has been added to the queue, and if the receiver is living in another thread, we notify the event dispatcher of that thread by calling QAbstractEventDispatcher::wakeUp. This will wake up the dispatcher if it was sleeping while waiting for more events. If the receiver is in the same thread, the event will be processed later, as the event loop iterates.
Qt event loop is thread safe but not atomic.
Thread safety
As long as Object2OfThread2 state is always modified by the thread associated with Thread2, there won't be any race conditions. At most one slot will be executed at any time.
Atomicity
The order of execution of slots is governed by :
usual thread preemption
The order in which the connections were made to this slot.
The other slots connected to the signal.
So I would not advise to assume a specific order of execution for a given slot.
what if Thread1 and Thread3 both post a signal simultaneously to Thread2's event loop
First, it is different signals : two threads cannot emit the same signal of the same object as this object resides in only one QObject
The signal connected first wins, assuming these signals are only connected to Object2OfThread2 even if they are "posted" simultaneously.
If for instance Thread1 signals are connected to other signals\slots, and those connections are made before Object2OfThread2, &Object2::Slot, they will be processed before being posted on Object2OfThread2 event loop. If the signals emitted simultaneously, Thread3 signal will be the first queued, so the first to execute.

How to quit the event loop of a worker QThread

I'm writing an application with a button to start/stop a worker thread (which implements QThread).
The worker thread keeps scheduling a job every few milliseconds.
To terminate the worker thread, I'm calling worker.quit() (worker.exit(0) doesn't work either) method from the GUI thread and waiting the finished signal to be fired.
The problem is that even though the finished signal is fired, the thread isn't terminated.
Here is a minimal example:
https://gist.github.com/NawfelBgh/941babdc011f07aa4ab61570d7b88f08
Edit
My interpretation of what happened was wrong: The worker thread was being terminated but the method iter was getting executed in the main thread as said by #sergey-tachenov and as confirmed from the logging generated with the code:
void run() {
std::cout <<"From worker thread: "<<QThread::currentThreadId() << std::endl;
...
void iter() {
std::cout <<"From thread: "<<QThread::currentThreadId() << std::endl;
...
void MainWindow::on_pushButton_clicked()
{
std::cout <<"From main thread: "<<QThread::currentThreadId() << std::endl;
I switched to a different design which doesn't rely on QTimers. But I didn't submit it as an answer since the title of this question is "How to quit the event loop of a worker QThread".
The thread is terminated. Only your timer runs not in the thread you've started but in the main thread, that's why it isn't stopped. This is because it uses queued connections by default and the thread object lives in the thread in which it was created which is the main thread. To fix it:
Do not subclass QThread. It's usually a bad idea unless you want to actually extend QThread's functionality.
Create a separate worker object that inherits QObject.
Use moveToThread to move the worker object to the created thread. It will cause all its slots to fire actually in the thread. If you use default or queued connections, that is.
The QThread docs provide an excellent example on that (the first one).
Note that if you actually want to use data provided by the thread to update GUI, you'll have to somehow correctly publish that data to the GUI thread (possibly using emit and queued connections) instead of trying to update GUI directly from the thread. And if you want to access shared data, you probably need to guard it with a QMutex, not like you do with your shared counter.

Blocking thread for wait queue

I have applications with 2 threads. In first (main) thread I want to generate some message and send it to second thread. Is there method to blocked thread for wait incoming message (like a queue in embended OS(FreeRTOS, TNKernel etc))?
while (true) {
waitQueue(TIMEOUT_INFINITY);
}
in waitQueue(TIMEOUT_INFINITY); current thread becomes blocked, when in main thread generates some message waitQueue releases thread.
The natural way for doing this in Qt is calling QThread::exec() in the thread (which is what the default implementation for QThread::run() do).
after that to execute a QObject instance (worker object)'s slots in that thread, you can set the instance's affinity to the new thread using QObject::moveToThread(), then when a signal connected to some slot in that instance is emitted, the slot will be invoked in the new thread.
Instantiating a QThread provides a parallel event loop, allowing QObject slots to be invoked in a secondary thread. Subclassing a QThread allows the application to initialize the new thread before starting its event loop, or to run parallel code without an event loop.
see QThread class, QObject class, Threads and QObject, along with Qt event loops.
Hope this helps. . .

QT Is a slot launched in a separate thread

I have done some research on this topic . the thread at SO also caught my interest and I wanted to summarize my understanding and be corrected if I am going wrong on a certain path and also wanted to know how QueuedConnection would work.
Here is my understanding followed by the question.
Signals can be connected manually to slots primarily through two different ways first way is using direct connection and the second way is queued connection. In case of a direct connection if the slot method that is attached to the signal is in the same thread then the slot method is called sequentially (as if it was just another method) however incase the slot is in a different thread from where the signal is launched then QueuedConnection would launch it when it finds it appropriate. (Now In this case I am not sure if it would launch a new thread or how it would proceed on doing that)
Slots don't belong to any particular thread, as they are just plain functions. But objects do. If you connect a signal to a slot by QueuedConnection, the signal emission will create an event and send that into the event queue of the target. Qt will arrange that your slot will be called when internally processing that event.
As for all events, they are processed in the thread of the object's thread affinity. You can change that thread by calling moveToThread on the target object.
In multithread environement when sender and recievr object is in diffrent thread.
Qt::QueuedConnection
What is happening when emiting thread? it simply emits( internally
postevent, to reciever threads message queue) and resume emiter
thread( not blocking).
what is happening on reciever thread, after executing above
statement? The slot is invoked when control returns to the event loop
of the receiver's thread.
Qt::BlockingQueuedConnection
What is happening on emiting thread ? it emits( internally sendEvent,
to reciever message queue) and block emiter thread until receiver
slot returnes.(Blocking).
what happening on receiever thread ? The slot is invoked when control
returns to the event loop of the receiver's thread.
Roughly speaking, for QueuedConnection Qt will make a queue of received signals for the thread the slot belongs to, and will launch them one by one in order they are stored in the queue when the thread becomes available (it finishes whatever it was doing and returns to event loop).
No new thread will be launched - slot belongs to some thread, so execution will be performed in that thread.

Qt signals reach UI thread with noticeable delay

I have a worker thread in my application, which occasionally recieves information that should be quickly displayed in QML UI. When I have such portion of information, I emit signal, which is received by object that lives on UI thread.
I want this process to be very responsive, so that changes are displayed in QML UI as quickly as possible (this matters because worker thread handles external controller, and I want the shortest "critical path" between user interaction with controller and UI change).
However I discovered, that the time difference between emit signal() and slot called in UI thread is always 20-40 milliseconds. Why so?
What can I do to speed up this? I tried calling QCoreApplication::processEvents() in worker thread after signal is emitted, but this barely changes anything.
Some thoughts:
Can I call processEvents but for UI thread somehow?
Use event with high priority instead of signal. Will it help?
OS: Win8.1, Qt 5.5
When you emit a signal from a worker thread to the UI thread, it is put into the UI event queue, and delivered when the event queue is pumped and reaches that message. If your worker thread is a higher priority than your UI thread, then the UI thread will have to wait until the worker thread blocks. If the worker thread is the same priority it will complete it's time quanta, which may be 20ms. You can make your signal connect Direct rather than Queued, and then you will need to take care of thread safety yourself.