QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?
-
Hello,
I’m wondering how isQIODevice::waitForReadyRead(int msecs)
working.If I don’t use it but rather async communication with my device, during the time I’m waiting for the response (send command, wait response) I need to manually block the main thread until the response is received. So there is no choice to
moveToThread
the communication handler to another thread than the main one and use awaitcondition
?How
QIODevice::waitForReadyRead(int msecs)
is working to avoid creating a thread to handle the communication? The event loop should be blocked during that wait no?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
how is QIODevice::waitForReadyRead(int msecs) working.
It does what you can already assume from its name...
It blocks the current thread untilQIODevice::readyRead()
or the time interval has passed.How QIODevice::waitForReadyRead(int msecs) is working to avoid creating a thread to handle the communication?
You don't want to do this in your main thread anyway, since it, well, blocks/waits until... (see above).
-
It does what you can already assume from its name...
It blocks the current thread until QIODevice::readyRead() or the time interval has passed.yeah my question is how is it working underneath… without a threading mechanism. How can it block and be awaken by a signal?
You don't want to do this in your main thread anyway, since it, well, blocks/waits until... (see above).
Well I’m developing a library. I’ve sync issue between the caller loop that uses a timer and the one of my library waiting for the request response. That is why I’m thinking to go async and use a dedicated thread and a waitcondition.
What’s wrong with this approach? Is there other solutions? -
It does what you can already assume from its name...
It blocks the current thread until QIODevice::readyRead() or the time interval has passed.yeah my question is how is it working underneath… without a threading mechanism. How can it block and be awaken by a signal?
You don't want to do this in your main thread anyway, since it, well, blocks/waits until... (see above).
Well I’m developing a library. I’ve sync issue between the caller loop that uses a timer and the one of my library waiting for the request response. That is why I’m thinking to go async and use a dedicated thread and a waitcondition.
What’s wrong with this approach? Is there other solutions?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
yeah my question is how is it working underneath… without a threading mechanism. How can it block and be awaken by a signal?
Since the default implementation in
QIODevice
does nothing and it all relies on the actual use case, whether you are usingQNetworkReply
or aQSerialPort
or... whatever, just check the source to see what it does exactly.For a serial connection, it's there:
I’ve sync issue between the caller loop that uses a timer and the one of my library waiting for the request response
You can use the async API.
AFAIK everyQIODevice
has one.Connect the signals and handle the new data in a function connected to it.
Then just don't callwaitFor...
, which will stop the current thread right there until the signal "unblocks" it. -
For a serial connection, it's there: https://codebrowser.dev/qt6/qtserialport/src/serialport/qserialport_unix.cpp.html#_ZN18QSerialPortPrivate16waitForReadyReadEi
ok it's an active while loop with a timer...
Then just don't call waitFor..., which will stop the current thread right there until the signal "unblocks" it.
what is the
waitFor
you are talking about? can we be awaken by a signal without aQWaitCondition
? -
For a serial connection, it's there: https://codebrowser.dev/qt6/qtserialport/src/serialport/qserialport_unix.cpp.html#_ZN18QSerialPortPrivate16waitForReadyReadEi
ok it's an active while loop with a timer...
Then just don't call waitFor..., which will stop the current thread right there until the signal "unblocks" it.
what is the
waitFor
you are talking about? can we be awaken by a signal without aQWaitCondition
?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
what is the waitFor you are talking about?
You did not mention what device you are using. A network device or do you have a serial port connection?
In case of the latter there are nice examples which illustrate both approaches:
can we be awaken by a signal without a QWaitCondition ?
AFAIK you don't need
QWaitCondition
when using theQIODevice
async API. -
You did not mention what device you are using. A network device or do you have a serial port connection?
I'm using a serial port.
In case of the latter there are nice examples which illustrate both approaches:
I've seen the examples and in general I'm used to the async approach for sockets.
AFAIK you don't need QWaitCondition when using the QIODevice async API.
So how would you do? I'm developing a lib that should reply to request from the main program and at the same time transfer the request on the serial port, and once the response is received on the serial port I should signal, and wake up my main method... I don't see how to do it without a thread and a QWaitCondition.... (if using async approach and not using active waiting (while loop with a sleep...)
-
For a serial connection, it's there: https://codebrowser.dev/qt6/qtserialport/src/serialport/qserialport_unix.cpp.html#_ZN18QSerialPortPrivate16waitForReadyReadEi
ok it's an active while loop with a timer...
Then just don't call waitFor..., which will stop the current thread right there until the signal "unblocks" it.
what is the
waitFor
you are talking about? can we be awaken by a signal without aQWaitCondition
?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
can we be awaken by a signal without a QWaitCondition ?
That's why we have readyRead() signal. You don't need (and should not even consider without a very valid reason) blocking approach.
You simply connect your slot to any of the ready...() signals and then proceed.
Now, depending if you're dealing with a serial port or network things might go different to some extent, so please read the available documentation very carefully.
(I am updating before posting since new answer arrived)
@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
So how would you do?
Like above. Connect to the signal and process the data available at the moment.
-
@artwaw I think you didn't get my usecase. I want to deliver a blocking service to the main app. So I've to wait. I don't want an active waiting loop. That is why the other only solution I see is to use a
QWaitCondition
Do I miss something? -
@jsulm that's my question for performance question AND debugging: use the async architecture for I/O (so I'm sure I'm not loosing any frames) but do a blocking service. So how? the only way I see would be to put the I/O in a thread and use a
QWaitCondition
.
I'm wondering what do you think I can gain doing that? if this is "common" or not... -
@jsulm that's my question for performance question AND debugging: use the async architecture for I/O (so I'm sure I'm not loosing any frames) but do a blocking service. So how? the only way I see would be to put the I/O in a thread and use a
QWaitCondition
.
I'm wondering what do you think I can gain doing that? if this is "common" or not... -
@mbruel I don't understand the problem. Why would you lose frames?
I want to make sure and test also the perf. I've some synchronization issues during my testing. probably due to the state machine but I'm looking all the directions. One would be to be async to be sure no frame ismissed cause we're in a wrong state.
Is it not more performant to use a
QWaitCondition
lock in the main thread instead of an active wait?... (embedded device, the less resources the better) -
@mbruel I don't understand the problem. Why would you lose frames?
I want to make sure and test also the perf. I've some synchronization issues during my testing. probably due to the state machine but I'm looking all the directions. One would be to be async to be sure no frame ismissed cause we're in a wrong state.
Is it not more performant to use a
QWaitCondition
lock in the main thread instead of an active wait?... (embedded device, the less resources the better)@mbruel
Don't know what you are saying about losing frames of what it has to do with sync vs async, but let's leave that.What is your "active wait"? What makes you think calling
waitForReadyRead()
is any more "active waiting" than your ownQWaitCondition
? If you really want to know what the former does you can look at the source, but I doubt there is anything "active" about the waiting which differs from, say,QWaitCondition
. You can always run withwaitForReadyRead()
and examine CPU activity during it to verify. -
Tbh I don't understand what QWaitCondition has to do with all this here and how this should in any way work with a QIODevice...
Creating problems without any needs or evidence that it does not work as written in the documentation...
-
Tbh I don't understand what QWaitCondition has to do with all this here and how this should in any way work with a QIODevice...
Creating problems without any needs or evidence that it does not work as written in the documentation...
@Christian-Ehrlicher said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Tbh I don't understand what QWaitCondition has to do with all this here and how this should in any way work with a QIODevice...
well the reason is simple: thread the I/O to make sure we don't miss frames...
Does it not make sense? -
@mbruel
Don't know what you are saying about losing frames of what it has to do with sync vs async, but let's leave that.What is your "active wait"? What makes you think calling
waitForReadyRead()
is any more "active waiting" than your ownQWaitCondition
? If you really want to know what the former does you can look at the source, but I doubt there is anything "active" about the waiting which differs from, say,QWaitCondition
. You can always run withwaitForReadyRead()
and examine CPU activity during it to verify.@JonB said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Don't know what you are saying about losing frames of what it has to do with sync vs async, but let's leave that.
good idea :)
What is your "active wait"? What makes you think calling waitForReadyRead() is any more "active waiting" than your own QWaitCondition? If you really want to know what the former does you can look at the source, but I doubt there is anything "active" about the waiting which differs from, say, QWaitCondition. You can always run with waitForReadyRead() and examine CPU activity during it to verify.
active wait to me is while(1) or for(;;) using a sleep like the implementation of
waitForReadyRead
.
I suppose it is more CPU consuming than a QWaitCondition lock on a Mutex where the thread has nothing to do if locked. Am I wrong? -
@JonB said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Don't know what you are saying about losing frames of what it has to do with sync vs async, but let's leave that.
good idea :)
What is your "active wait"? What makes you think calling waitForReadyRead() is any more "active waiting" than your own QWaitCondition? If you really want to know what the former does you can look at the source, but I doubt there is anything "active" about the waiting which differs from, say, QWaitCondition. You can always run with waitForReadyRead() and examine CPU activity during it to verify.
active wait to me is while(1) or for(;;) using a sleep like the implementation of
waitForReadyRead
.
I suppose it is more CPU consuming than a QWaitCondition lock on a Mutex where the thread has nothing to do if locked. Am I wrong?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
I suppose it is more CPU consuming than a QWaitCondition
Did you observe high CPU usage when using waitForReadyRead, or do you just assume it consumes a lot of CPU?
waitForReadyRead does not use a lot of CPU, so don't know what you're trying to optimize here... -
@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
I suppose it is more CPU consuming than a QWaitCondition
Did you observe high CPU usage when using waitForReadyRead, or do you just assume it consumes a lot of CPU?
waitForReadyRead does not use a lot of CPU, so don't know what you're trying to optimize here... -
@JonB said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Don't know what you are saying about losing frames of what it has to do with sync vs async, but let's leave that.
good idea :)
What is your "active wait"? What makes you think calling waitForReadyRead() is any more "active waiting" than your own QWaitCondition? If you really want to know what the former does you can look at the source, but I doubt there is anything "active" about the waiting which differs from, say, QWaitCondition. You can always run with waitForReadyRead() and examine CPU activity during it to verify.
active wait to me is while(1) or for(;;) using a sleep like the implementation of
waitForReadyRead
.
I suppose it is more CPU consuming than a QWaitCondition lock on a Mutex where the thread has nothing to do if locked. Am I wrong?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
active wait to me is while(1) or for(;;) using a sleep like the implementation of waitForReadyRead.
while(1)
alone will utilize 100% of the available resources for this process/thread and runs as fast as possible.
However puttingwaitForReadyRead
with or without timeout in, should avoid that, since it doesn't cycle in idle like a madman anymore, but is waiting for thereadyRead()
call instead (see @jsulm 's comment above)."Assuming" CPU or memory utilization is another thing. Most tools aren't very accurate about that, esp. when you run your own non-optimized code. Same with memory leaks.
I don't understand your struggles here... you are asking about sync/async and later you mention that you want a blocking approach in your library?
Also as it's clear now that you are usingQSerialPort
, there are lots of (good) examples out there (officially by Qt and by other users) on how to implement (non-)blocking serial communication. -
@Christian-Ehrlicher said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Tbh I don't understand what QWaitCondition has to do with all this here and how this should in any way work with a QIODevice...
well the reason is simple: thread the I/O to make sure we don't miss frames...
Does it not make sense?@mbruel said in QIODevice::waitForReadyRead question. comparison with async method and usage of waitcondition?:
Does it not make sense
Absolutely not and we try to tell you this bit you don't care for whatever reason...
If you would really loose bytes (not frames BTW - it's a stream) then this would be a Qt bug.