异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件? [英] Assynchronous serial comms: why does ReadFile() set the event in the OVERLAPPED struct?

查看:20
本文介绍了异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我利用各种来源拼凑了一些(多线程)代码,以便从/向串行端口读取和写入.一切正常……除了从串行端口读取数据的线程中的循环无意中进行了忙等待.基本上重复发生的是:

I have drawn on various sources to piece together some (multi-threaded) code to read and write from/to a serial port. It all works fine... except that the loop in the thread that does the reading from the serial port unintentionally does a busy wait. Essentially what happens repeatedly is:

  • 一个事件(在读取循环之外创建)被重置,其句柄用作 OVERLAPPED 结构中的 hEvent 成员.
  • ReadFile() 被传递给 OVERLAPPED 结构(以及其他参数)并立即返回
  • WaitForSingleObject() 等待 OVERLAPPED 结构中的事件,但总是立即返回,因为事件总是在 ReadFile() 之后设置
  • GetOverlappedResult() 然后传递相同的 OVERLAPPED 结构,成功返回,但通常只读取 0 个字节

我的期望是事件的全部意义在于在有数据可供读取时发出信号.但是 ReadFile() 设置了事件,那么有什么意义呢?我错过了什么?

My expectation was that the whole point of the event was to signal when there is data available to read. But ReadFile() sets the event, and so what is the point? What am I missing?

以下精简代码演示了我的系统(我已连接 COM3)上的问题.完整的代码可以很愉快地读写……但读者会遇到上述情况:

The following stripped-back code demonstrates the issue on my system (I have COM3 connected). The full code quite happily reads and writes... but the reader suffers from the condition described above:

HANDLE portHandle = CreateFile( "COM3",
                                GENERIC_READ | GENERIC_WRITE,
                                0,
                                NULL,
                                OPEN_EXISTING,
                                FILE_FLAG_OVERLAPPED,
                                NULL );  // succeeds
HANDLE readerEvent = CreateEvent( 0, TRUE, FALSE, _T( "Rx Event" ) );  // succeeds
char buffer[ 200 ];
DWORD bytesRead;
OVERLAPPED reader;
memset( &reader, 0, sizeof( reader ) );
reader.hEvent = readerEvent;
ResetEvent( readerEvent );
ReadFile( portHandle, buffer, 200, &bytesRead, &reader );
if ( WaitForSingleObject( reader.hEvent, 2000 ) == WAIT_OBJECT_0 )
{
    // always true, never has to wait on the event.
}

推荐答案

找到了:ReadFile 函数的文档包含这一段:

Found it: the documentation for the ReadFile function contains this paragraph:

  • 从通信设备读取数据时,ReadFile 的行为由设置的当前通信超时决定,并使用 SetCommTimeouts 和 GetCommTimeouts 函数检索.如果未能设置超时值,可能会出现不可预测的结果.有关通信超时的详细信息,请参阅 COMMTIMEOUTS.

我根本没有使用 SetCommTimeouts().执行 GetCommTimeouts() 并检查结果显示端口的设置是 COMMTIMEOUTS 文档中本段中描述的值:

I was not using SetCommTimeouts() at all. Performing a GetCommTimeouts() and inspecting the results showed the port's settings were the values described in this paragraph from the COMMTIMEOUTS documentation:

  • MAXDWORD 值与 ReadTotalTimeoutConstant 和 ReadTotalTimeoutMultiplier 成员的零值相结合,指定读取操作将立即返回已接收的字节,即使尚未接收到任何字节.

这篇关于异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆