Yea, I'm going to have to agree with Denis over Roland. In general it's not good to do synchronous operations (expecially I/O) in the main thread, but Qt I/O is mostly* asyc.
 
*caveat: data reading/writng is async, but things like QDir::mkDir() are sync. So if you're on a slow 5400RPM disk with a swap file on it on a system that is actively swapping, in a deep direcyory structure, on old fielsystems, it might take a while (100s of ms).
 
I'm not sure if Qt wants fully async I/O as I've witnessed what it does to a code base - some functions are async others are sync and you don't want that mess in your code. Coroutines will be a C++ thing (C++20), but I migh prefer the clarity of just being syncronous in your own thread. A lot of people don't realize that as soon as you ask for I/O your thread gets suspended by the kernel anyway. There are corner cases where you can get slughtly better performance because you can avoid the context switch, but the penalty on codebase is large as readability suffers. If the async nature could be completely hidden, that would be fine. But cyrrently in JS and Python, it's an imperfect abstraction.
 
 
Sent: Friday, April 05, 2019 at 5:45 AM
From: "Denis Shienkov" <denis.shien...@gmail.com>
To: rol...@logikalsolutions.com
Cc: h...@gmx.com, interest@qt-project.org
Subject: Re: [Interest] Parsing data from serialport
> Never ever ever do I/O in the main GUI thread of a Qt application.
 
Why not? It is an asynchronous. You can do I/O in a main thread, but handle data in a separate thread (e.g. to parse it). Of course, it depends on the used communication protocol and etc.
A main limitation is that on Windows all I/O stops when a user hold-on the application window (ot to drag it, or do resizing). It is a Windows 'feature'.
 
So, yes, in a common case it is makes sense to move the QSerialPort object to the different thread (a concept of workers).
 
> Real world serial comm is fraught with peril. I've been doing it since the days of DOS 3.1.
 
It's not true.
 
> Unless something has dramatically changed in QSerialPort, readyRead is only emitted for the first character in the buffer because there is no concept of block or packet. A UART handles one byte at a time.
 
It's not true too. The readyRead() will be triggered when the device's handle/descriptor becomes 'signalled/activated' (when something comes into FIFO of driver), in this case the QSerialPort reads all data which are in this time in the FIFO (there are may be some bytes). So, no any byte-per-byte handling as you say.
 
> When you get a readyRead and fail to completely empty the buffer, that's it. You never get another one.
 
I'm don't understand what do you mean...
 
> When QSerialPort was taken from Playground and had all its method names changed, there was an odd timing bug too. In a production system running multiple ports of embedded target the code loading the next byte into the class buffer (perhaps not completely Qt code as it could have been in the device driver). The adding of the next byte could begin after readLine() determined how many bytes were in the buffer but prior to actually pulling them. The new byte got added. One less than a full buffer got read and readyRead never fired again because the next byte wasn't being written to a pristine empty buffer.
 
I don't know about what you say... It is trash for my opinion.. For you has been provided a good code example how to read the lines:
 
>     QSerialPort * port;
>     QObject::connect(port, &QIODevice::readyRead, port, [port] () -> void  {
>         while (port->canReadLine())  {
>             QByteArray data = ""> >             // emit with data as argument and do the parsing
>         }
>     });
 
BR,
Denis
 
 
 
 
пт, 5 апр. 2019 г. в 10:38, <rol...@logikalsolutions.com>:

Quoting interest-requ...@qt-project.org:

> I think the point is that there's little reason to poll the serial port if
> you can react to the event. Exactly what you'd do if you had a network
> socket. Qt already does the heavy lifting for you, so you only need to
> react to the signal and read as much as you want/need. Basically:
>
>     QSerialPort * port;
>     QObject::connect(port, &QIODevice::readyRead, port, [port] () -> void  {
>         while (port->canReadLine())  {
>             QByteArray data = ""> >             // emit with data as argument and do the parsing
>         }
>     });
>
> Whether you have the port in another thread or not is irrelevant in this
> case, either can work fine (unlike your while-sleep loop).

Never ever ever do I/O in the main GUI thread of a Qt application. 
It's a recipe for disaster despite the countless examples you will 
find posted on-line and even in the Qt examples themselves. Those 
database examples are really nice. Try testing them with a million+ 
row table.

Real world serial comm is fraught with peril. I've been doing it since 
the days of DOS 3.1.

Before anyone goes running off and using the above lambda, they need 
to consider a few things.

Unless something has dramatically changed in QSerialPort, readyRead is 
only emitted for the first character in the buffer because there is no 
concept of block or packet. A UART handles one byte at a time.

When you get a readyRead and fail to completely empty the buffer, 
that's it. You never get another one.

When QSerialPort was taken from Playground and had all its method 
names changed, there was an odd timing bug too. In a production system 
running multiple ports of embedded target the code loading the next 
byte into the class buffer (perhaps not completely Qt code as it could 
have been in the device driver). The adding of the next byte could 
begin after readLine() determined how many bytes were in the buffer 
but prior to actually pulling them. The new byte got added. One less 
than a full buffer got read and readyRead never fired again because 
the next byte wasn't being written to a pristine empty buffer.


--
Roland Hughes, President
Logikal Solutions
(630) 205-1593

http://www.theminimumyouneedtoknow.com
http://www.infiniteexposure.net
http://www.johnsmith-book.com
http://www.logikalblog.com
http://www.interestingauthors.com/blog
http://lesedi.us

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest
_______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to