PDA

View Full Version : QEventLoop with QProcess Questions



zodd
22nd January 2019, 15:18
Hello,

I use several QProcess to start several daemons on Linux Os and "capture" there output in a slot when the signal readyRead() is emit by the QProcess.

But sometimes there is a large amount of "payload" on the differents ouputs and some output datas seems to be lost.

So to remedy to this issue, I use a thread with an infinite loop for each QProcess and it's seems to work, but I heard about the use of QEventLoop and maybe it could be a better solution :

http://doc.qt.io/qt-5/qeventloop.html

but I don't find any simple example that I'm able to understand and implement QProcess with it..

In summary, I would like to be sure that' I don't miss any data ouput on something like that:



MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
(...)
QString programFoo = "sh";
QStringList argumentsFoo;
argumentsFoo << "-c" << "./myFood";
myDaemonFoo->start(programFoo, argumentsFoo);

connect(myDaemonFoo, SIGNAL(readyRead()), this, SLOT(readDaemonFooOutput()));

QString programBar = "sh";
QStringList argumentsBar;
argumentsBar << "-c" << "./myBard";
myDaemonBar->start(programBar, argumentsBar);

connect(myDaemonBar, SIGNAL(readyRead()), this, SLOT(readDaemonBarOutput()));
}
void MainWindow::readDaemonFooOutput()
{
//display output in QtextEdit
}

void MainWindow::readDaemonBAROutput()
{
//display output in QtextEdit
}

My problem with using QThreads, is that I have to emit the result from the secondary thread to the main windows thread or/and I have to protect datas with a Qmutex and I'm afraid that I can still miss some data output from the daemon.

If someone can help me or give me some advices,
Thank you.

tuli
22nd January 2019, 17:44
Signal-Slot connections work across thread boundaries.



on the differents ouputs and some output datas seems to be lost.

That seems unlikely, probably there is a bug in your code.



Consider using the more specific specific


void readyReadStandardError()
void readyReadStandardOutput()

signals and show how you read the output in your slots.

zodd
22nd January 2019, 17:52
Thank you for your answer..

So what you say is , if I use two thread A and B and "connect" them with a signal emit by A and process in a slot in B, I don't have to worry ?

I'm doing some tests with Threads connected by signal-slot and it seems to be ok. My program is logging now and I'll check if it's really ok.

tuli
22nd January 2019, 19:16
So what you say is , if I use two thread A and B and "connect" them with a signal emit by A and process in a slot in B, I don't have to worry ?

Yes. Look connectin types: https://doc.qt.io/qt-5/qt.html#ConnectionType-enum


Default is AutoConnection


(Default) 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.

zodd
23rd January 2019, 08:57
Thank you for your clarification.

So as I didn't specified anything, it's the Qt::QueuedConnection which is used.

I've got just one other question:

what happens if a second signal is emited by thread A while the previous slot in thread B "launched" by the previous signal isn't finised to be executed?

tuli
23rd January 2019, 09:25
It will be "queued" (queued connection), so it will be executed after the previous signal was handled.

Slots are executed within the context of the thread the slot lives in. All this is handled by QEventLoop in the background by Qt.

zodd
23rd January 2019, 10:11
ok, thank you, that's what I don't really well understand... how do QEventLoop operate.. how many slot can be queued? Should I use "directly" QEventLoop..etc..

tuli
25th January 2019, 22:14
Ideally you never deal wit the event loop yourself. Every Qt-Thread automatically does this for you.

I dont think there is a limit on the number of queued signals, no.

d_stranz
26th January 2019, 18:49
Ideally you never deal wit the event loop yourself. Every Qt-Thread automatically does this for you.

Correct. The major exception to this general rule is if you have a thread (especially the GUI thread) in which you are doing some time-consuming computation. If the computation doesn't pause every so often to allow the event loop to run and process pending events, your GUI will "freeze" until the computation is finished.

In this case, the usual solution is to do something like this:



while ( !computationDone )
{
computeALittleBit();
QCoreApplication::processEvents();
}


Without the call to processEvents() nothing happens to the GUI and it freezes.