Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 为什么QSerialPort::writeData使用单次触发计时器开始写入?_Windows_Qt_Serial Port_Qtserialport - Fatal编程技术网

Windows 为什么QSerialPort::writeData使用单次触发计时器开始写入?

Windows 为什么QSerialPort::writeData使用单次触发计时器开始写入?,windows,qt,serial-port,qtserialport,Windows,Qt,Serial Port,Qtserialport,我试图理解Qt的串行端口模块,但不太熟悉Qt如何处理异步I/O。在Windows上,该方法将要写入的数据放入环形缓冲区,然后启动单次触发的QTimer,以便在其超时信号触发时实际执行写入: qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize) { Q_Q(QSerialPort); writeBuffer.append(data, maxSize); if (!writeBuffer.

我试图理解Qt的串行端口模块,但不太熟悉Qt如何处理异步I/O。在Windows上,该方法将要写入的数据放入环形缓冲区,然后启动单次触发的
QTimer
,以便在其
超时
信号触发时实际执行写入:

qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
    Q_Q(QSerialPort);
    writeBuffer.append(data, maxSize);
    if (!writeBuffer.isEmpty() && !writeStarted) {
        if (!startAsyncWriteTimer) {
            startAsyncWriteTimer = new QTimer(q);
            QObjectPrivate::connect(startAsyncWriteTimer, &QTimer::timeout, this, &QSerialPortPrivate::_q_startAsyncWrite);
            startAsyncWriteTimer->setSingleShot(true);
        }
        if (!startAsyncWriteTimer->isActive())
            startAsyncWriteTimer->start();
    }
    return maxSize;
}
readData
方法不以这种方式使用计时器,而是直接调用
ReadFileEx


与只调用
writefilex
相比,单次触发计时器的作用是什么?

对于间隔为0的
QTimer
有一种特殊情况:一旦控件返回到。Unix/Linux上的实现可以,但不使用QTimer,而是有一个子类
QSocketNotifier
,当端口能够写入时将调用该子类。这两种实现都意味着您将缓冲数据,并在返回到主事件循环后将其写出

我可以想到这样做的两个原因:

  • POSIX和Win32串行API之间有一些不同之处,它们要求以这种方式构造代码。据我所知,情况并非如此
  • @Mike在评论中说:这将允许数据在写入之前被缓冲

缓冲似乎是最可能的原因,因为对要写入的每段数据进行系统调用将是一个相当昂贵的操作。

对于间隔为0的
QTimer
有一种特殊情况:一旦控件返回到。Unix/Linux上的实现可以,但不使用QTimer,而是有一个子类
QSocketNotifier
,当端口能够写入时将调用该子类。这两种实现都意味着您将缓冲数据,并在返回到主事件循环后将其写出

我可以想到这样做的两个原因:

  • POSIX和Win32串行API之间有一些不同之处,它们要求以这种方式构造代码。据我所知,情况并非如此
  • @Mike在评论中说:这将允许数据在写入之前被缓冲

缓冲似乎是最可能的原因,因为对要写入的每段数据进行系统调用将是一个相当昂贵的操作。

一个优点是,这允许将多个连续写入调用合并为对
writeFilex
的一个调用(例如:
port.write(“a”);port.write(“b”);port.write(“c”)
都被翻译成
writefile(“abc”);
)。我不确定是否还有更重要的一个,可能是为了实现异步处理。根据设备驱动程序的实现和要发送的数据的大小,可能有人认为直接调用WriteFilex将是一个同步过程。或者,实现WriteData的超时错误检测过程的目的可能只是一个错误。一个优点是,这允许将多个连续的写调用合并为对
WriteFilex
的一个调用(例如:
port.write(“a”);port.write(“b”);port.write(“c”);
都转换为
WriteFilex(“abc”);
). 我不确定是否还有更重要的一个,可能是为了实现异步处理。根据设备驱动程序的实现和要发送的数据的大小,可能有人认为直接调用WriteFilex将是一个同步过程。或者,可能打算实现WriteData的超时错误检测过程的只是一个错误。