Unsolved Signal Slot problem in a thread [EDIT-UPDATE]
-
@VRonin said:
Is a race condition (serPort needs thSer event loop to delete itself)
change connect(serPort, SIGNAL(finished()), thSer, SLOT(quit())); to connect(serPort, SIGNAL(destroyed()), thSer, SLOT(quit()));It's enough to switch the order of connect statements.
connect(serPort, SIGNAL(finished()), serPort, SLOT(deleteLater())); connect(serPort, SIGNAL(finished()), thSer, SLOT(quit()));
Is perfectly fine, as pending delete events will be processed before exiting the event loop.
-
@kshegunov said:
It's enough to switch the order of connect statements.
True given the current implementation. I thought the order of execution of slots should not be considered deterministic (even if it has been deterministic at least since Qt4). Or does that rely on the fact that the first connection is implicitly a directconnection while the second is a queuedconnection? if that is the case then the order of connection doesn't matter anyway
-
@VRonin said:
I thought the order of execution of slots should not be considered deterministic
When across threads it can't be deterministic. When using
Qt::DirectConnection
(I think it's documented) the order is in the order of connects.Or does that rely on the fact that the first connection is implicitly a directconnection while the second is a queuedconnection? if that is the case then the order of connection doesn't matter anyway
Nope, I was thinking of something else and got tangled up posting and reposting events in my head. Actually the order shouldn't matter anyway. I was thinking about this when I wrote the above:
When this signal is emitted, the event loop has already stopped running. No more events will be processed in the thread, except for deferred deletion events. This signal can be connected to QObject::deleteLater(), to free objects in that thread.
Basically the thread will process the last pending deferred deletions just before actually exiting the stack.
Kind regards.
-
Looks like QThread can take care of itself (I always used the destroyed signal, I won't in the future). scarp my initial answer
-
That is strange, I made the connectionsin the following order and all works
serPort = new SerialPort(); qDebug() << "connected" << connect(this,SIGNAL(writeCom(QString)),serPort,SLOT(updateMsg(QString)),Qt::QueuedConnection); thSer = new QThread; //thRead // serPort->moveToThread(thSer); //qDebug() << " 1Read" << connect(readPrt, SIGNAL(error(QString)), this, SLOT(errorString(QString))); connect(thSer, SIGNAL(started()), serPort, SLOT(process())); connect(serPort, SIGNAL(finished()), thSer, SLOT(quit())); connect(serPort, SIGNAL(finished()), serPort, SLOT(deleteLater())); connect(thSer, SIGNAL(finished()), thSer, SLOT(deleteLater()));
I have the while(), becauseI thought by reading the serial port (in paralel with MainWindow)until the condition (exit) is true. Why is not right?
void SerialPort::process(){
while(!exit) {
//read here serial port
}
emit finished();}
geetings and thank you very much
-
@yczo Because while you're in the loop the event loop is blocked and no signals will be emited:
while(!exit){ ... rcv = read(); if (*rcv != '\0') { QString qRcv(rcv); emit received(qRcv); // This signal will be emited after while loop is finished! } } //von while
-
Because while you're in the loop the event loop is blocked and no signals will be emited
Not true. Signals are emitted fine without an event loop (I sometimes use them like this when subclassing
QThread
). Also direct signal-slot connections will work fine. The thing that will not work is a deferred invocation (a queued connection) as it requires an active event loop.@jsulm has already given you the answer in his first post - you're blocking the event loop, so there will be no queued slots executed until you unblock it. This:
connect(this,SIGNAL(writeCom(QString)),serPort,SLOT(updateOutBuff(QString)),Qt::QueuedConnection);
requires a running event loop to work properly.
Kind regards.
-
A question: Then, I can not make infinite loops in a thread??? but I need to make an infinite loop in paralel with MainWindow, Is there another technique to do?
How can i make an infinite loop in paralele with MainWindow then?
Greetings, and thank you very much.
-
Hi,
Take a look at the mandelbrot example.
-
but I need to make an infinite loop in paralel with MainWindow, Is there another technique to do?
There is. Use the asynchronous API, as you were advised in your other thread. Connect the
QSerialPort::readyRead
signal to a slot in your worker object that will do the reading from the serial port.As for loops there can be loops made to run through the event queue but I see no good justification to do that here.
Kind regards.