How to guarantee signal delivery from multiple children - concurrency

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

Related

How can I prevent transmission of execution control to the last executed function when a Qt signal is emitted?

I have a Qt C++ program. I have a main driver MainWindow and a TCPClient class. The TCPClient class is used to communicate with a remote server, transmit some data over TCP, request for processing of the data and receive processed data from server. In my TCPClient class, I am using QAbstractSocket signal disconnected. This is emitted when the connection with the server is disconnected. In the function (slot) which handles this disconnect signal (ifDisconnected), onCompletionCallback function of the MainWindow is called. Now my question is how do I prevent the transmission of execution back to TCPClient after the said onCompletionCallback finishes executing. What's following is incomplete code describing the issue;
mainwindow.cpp
void MainWindow::on_connectButton_clicked()
{
std::function<void(void)> callback std::bind(&MainWindow::onCompletetionCallback, this);
tcpClient_ = new TCPClient(callback)->connectToServer(someData);
}
void MainWindow::onCompletetionCallback()
{
if(tcpClient_->isRequestSuccess())
{
QJsonDocument responseJson = tcpClient_->getResponse();
return; //When this finishes executing, I want to prevent the execution control to go back to TCPClient
}
}
TCPClient.cpp
void TCPClient::connectToServer(QJsonDocument requestJson)
{
// Removed code of other connect signals
connect(tcpSocket_, &QTcpSocket::disconnected, this, &TCPClient::ifDisconnected);
}
void TCPClient::ifDisconnected()
{
// Here the callback is called. After the callback finishes executing, I don't want execution to return to `TCPClient`.
onCompletionCallback_();
return;
}
How do I solve this problem. I need to use the signal disconnected because QAbstractSocket doesn't provide any utility function to check if the connection is available.
You cannot and you should not prevent that the signal handler returns to caller. Otherwise, you would corrupt your call stack.
The actual question (for me) is: What is the caller of signal handler?
To understand what I mean, please, read the Qt doc. about QObject::connect() with special attention to Qt::ConnectionType.
The default is Qt::AutoConnection which means:
If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
Qt::DirectConnection:
The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
The most common case (for me) are signal handlers called for modifications of GUI objects (i.e. widgets, etc.) which modify data or other widgets in response (in strict single-threading manner). In this case, it is Qt::DirectConnection i.e. the widget signal emitter is the caller of my signal handler.
A possible error (I did once) is to delete the widget which emitted the signal (e.g. handling a close button event of a dialog) – bad idea: I destroyed the widget with a pending method call on call stack. After returning from my signal handler it ended in a crash. The caller method (the signal emitter) had no instance anymore, or in other words: its this was invalidated. (It's like sawing the limb you sit on.) (Btw. deleteLater could be one solution for this. I found SO: How delete and deleteLater works with regards to signals and slots in Qt? concerning this.)
Considering your code sample
connect(tcpSocket_, &QTcpSocket::disconnected, this, &TCPClient::ifDisconnected);
I suspect this is a Qt::DirectConnection.
The other aspect: calling a main window function out of the TCP client thread is something which needs special attention as well. The caller is something in the TCP client thread but addresses an object (the main window) which resides in the (different) GUI thread. Phew. Everything (exept local variables) what is accessed in this called function must be mutex guarded if the GUI thread itself uses this as well.
So, what about the other options:
Qt::QueuedConnection:
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.
For communication between threads, IMHO, the Qt::QueuedConnection is the safer way: The TCP client emits a signal which results in a respective entry in the event loop of the GUI thread (assuming the main window was given as receiver object). The GUI thread will pick up this entry while processing its event loop. In this case, the event loop of GUI thread is the caller of the signal handler. The TCP client thread didn't wait after sending the signal request but continued its processing. If this is not desired the third option comes into play:
Qt::BlockingQueuedConnection:
Same as Qt::QueuedConnection, except that the signalling thread blocks until the slot returns. This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
The Qt::BlockingQueuedConnection lets the signal emitter (the TCP client) until the GUI thread has processed the signal handler. (The warning about the dead-lock is not effective here as the TCP client thread is the signaling thread where the GUI thread is the receiver.)
I'm a little bit uncertain what to recommend. I'm afraid your application needs a little bit re-design but for this the code sample is a little bit to incomplete.
A possible solution:
Introduce a Qt signal emitted when completion is required. The MainWindow::onCompletetionCallback() may be connected as signal handler to this TCP client signal using a Qt::BlockingQueuedConnection.
If the end of transmission is recognized it may perhaps destroy the TCP client thread. However, a thread which kills another thread is no good idea in general (and I'm not sure how Qt handles this "under the hood"). Therefore, a better concept would be: If the end of transmission is recognized the main thread flags the TCP client thread to leave it's main loop. Flagging could be done e.g. with a std::atomic<bool> (or you stay in Qt which has its own pendant QAtomicInt. The TCP client checks this flag in its main loop or at least after emitting a signal and exits in case.
A last hint:
If you are uncertain whether you understood the all the signal stuff correctly – I checked my understanding by putting a break point into the signal handler and inspecting the call stack when execution stopped at that break point. This is easy and straight forward (except you are dealing with mouse or drag & drop events).

Force Qt custom signal to be processed immediately?

I have a question about Qt and its signals/slots mechanism.
I have created a custom widget and in that I have created a custom SIGNAL (ShowMessage). This signal is connected to a SLOT, which displays the message (along with the specified timeout) in my main window's status bar.
Now, I have an operation in my class that takes a long time to execute, and it's blocking the UI. I was hoping to emit my signal before starting the operation and when it's finished, emit it again to update the status bar; something like this:
emit ShowMessage(message, timeout);
// Do the long operation
emit ShowMessage(newMessage, timeout);
But my problem is that it seems that Qt waits until the whole operation is finished, and only updates the status bar with newMessage.
Is there a way to somehow "force" immediate processing of my signal, because if I want to resort to threads, then my life will get much more complicated!
Is there a way to somehow "force" immediate processing of my signal
Yes, there is. :-).
After you show your first message, call QCoreApplication::processEvents(). This forces all pending events to be processed at the point of call. For example,
emit ShowMessage(message, timeout);
QCoreApplication::processEvents();
// Do the long operation
emit ShowMessage(newMessage, timeout);

Qt/C++ how to wait a slot when signal emitted

I have developed an app in Qt/C++, I have used signal/slot mechanism to interact between 2 threads. the first thread run the UI/TreeWidget and the second one run the framework
I got an issue on one action.
In the UI side, before starting my action, I'm connect signal/slot between UI and framework such as below in the treewidget.cpp
connect(&m_Framework, &Framework::RequestIfNameExist, this, &TreeWidget::RequestIfNameExist);
connect(this, &TreeWidget::SendAnswerIfNameExist, &m_Framework, &Framework::NotifIfNameExist);
The framework, start and send the RequestIfNameExist:
emit RequestIfNameExist(tmpname, item, fileInfo.isDir());
while(WaitingResponse == false){
usleep(200);
}
I have added a loop because I need to wait the feedback. Strange things is that in the treewidget.cpp, I never enter in
void TreeWidget::RequestIfNameExist(QString name, TreeWidgetItem *parent, bool isFolder) {
#ifdef PULS_LOG
QLOG_INFO() << "[TreeWidget] [RequestIfNameExist] ";
#endif
emit SendAnswerIfNameExist(isNameExist(name, parent), isFolder);
}
I never access to RequestIfNameExist in the TreeWidget but the signal is emitted.
I have also put a while loop in the framework to wait the feedback from TreeWidget
void Framework::NotifIfNameExist(QTreeWidgetItem *item, bool isFolder){
if(item != NULL)
item->isFolder = isFolder;
WaitingResponse = true;
}
Any idea why the signal emitted by framework never arrived on the treewidget ? is it coming from the while ??
Is there a way to not use while such as a "wait event" + timeout
Thanks
My first thought is that having either thread block until an operation in the other thread completes is a poor design -- it partially defeats the purpose of having multiple threads, which is to allow multiple operations to run in parallel. It's also liable to result in deadlocks if you're not careful (e.g. if both threads decide to emit-and-wait at approximately the same time!)
A better design would have the initiating method do the emit RequestIfNameExit and then return immediately, so that the initiating thread's event loop can continue running as usual during the operation. Then, when the other thread has done its work, it responds by emitting its own response-signal, causing the appropriate/connected slot-method in the first thread to be called, at which point the results are handled back in the first thread.
That said, if you insist on wanting to block the execution of the signal-emitting thread inside a method, until the other thread has finished executing the associated slot-method, you can get that behavior by setting the signal/slot connection's type to be Qt::BlockingQueuedConnection (the connection type can be specified via an optional extra argument to connect()). If you do that, then you emit call won't return until the slot-method (in the other thread) has finished executing. Given that, you can get the results from the other thread by passing a pointer to a data object as one of the arguments in the signal/slot method signature, and having the other thread populate that data object as necessary. When the emit returns you can just examine the contents of that data object to see the results.

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.