Qt signals reach UI thread with noticeable delay - c++

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.

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.

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.

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

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.

Infinite Thread that may or may not run a CDialog each loop

I am working on a MFC project where I need a separate loop that will run continually or once every few seconds, and each time it may or may not need to run a Dialog to get some input from the user. I was thinking of using AfxBeginThread, but from what I have read about it, it doesn't really work with a continuous loop.
Don't do it. You can't just rip dialogs off in worker threads. They can only be started in the main thread, because they need the message pump in order to function.
If all you want is a signal of some kind that fires every few seconds, then what you want is a timer. Set the timer for the timer period you want, and when your main thread processed the desired WM_TIMER message, you can pop up a dialog and do your thing.
If you want your worker thread to do some work, which may or may not include asking the user for information, then you'll want to look in to having your thread use PostMessage() to send a message to the main thread, process that message int he main thread by asking the user for data, and then sending a signal back to the worker thread with the input data. One way to accomplish the last bit is by calling QueueUserAPC() from the main thread with the worker thread's handle and a pointer to a function that does somethething with the newly-entered data.

How to guarantee signal delivery from multiple children

As part of a Linux benchmark application, I have a parent process that forks multiple children that will each perform a task in parallel. I'm using signals to coordinate between them since I'm looking for as accurate of timing as possible. Each child will prepare for the test, then enter a 'barrier' controlled by the parent via signals.
Once all the children have entered the barrier, the parent records the time stamp, and signals the child processes to begin. As soon as the child finishes each portion of the test they signal the parent before entering the next barrier. The parent is listening for these signals and once it receives them from all of the child processes, it records the completion time(s).
My problem is that the program terminates non-deterministically; the signals don't always get delivered. The signal handler could not be any simpler:
void sig_child_ready (int sig)
{
num_child_ready++;
}
num_child_ready is declared as volatile sig_atomic_t. I've tried using sigprocmask without success in a loop like this:
sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (num_child_ready < num_child)
{
/* waiting for child signals here */
sigsuspend (&oldmask);
}
sigprocmask (SIG_UNBLOCK, &mask, NULL);
I'm not sure how to proceed from here. Am I correct that sigprocmask is needed to 'queue' the signals so they are processed one by one?
Or, consider this hypothetical scenario: the parent receives a signal, is executing its handler, then receives ANOTHER identical signal. Is the signal handler called recursively? ie will it execute the second handler before returning to, and completing the first handler?
I'm just looking to make sure all of the signals are delivered as synchronously as possible.
Normal signals are not queued, and that's likely the cause of your problem.
If one signal arrives before the handler has been run for a past signal, they'll get merged and there's little you can do about that - you're probably better off using some other form of IPC to do this kind of synchronization.
You could use "realtime signals", which do get queued. You'd send signals with sigqueue() and
"receive" them with sigwaitinfo() or establishing a signal handler setting the SA_SIGINFO flag in a struct sigaction