c++ - 异步串行通信 : why does ReadFile() set the event in the OVERLAPPED struct?

标签 c++ visual-studio winapi

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

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

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

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

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 函数的文档包含这一段:

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

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

  • MAXDWORD 的值与 ReadTotalTimeoutConstant 和 ReadTotalTimeoutMultiplier 成员的零值相结合,指定读取操作将立即返回已接收到的字节,即使没有接收到字节也是如此。

关于c++ - 异步串行通信 : why does ReadFile() set the event in the OVERLAPPED struct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22138067/

相关文章:

c++ - 无法实现密码过滤器

c++ - Win32 键盘组合

c++ - 带有 roi 的 opencv 错误断言

c++ - 减少实时绘图数据的有效方法

c++ - gdb 将内存地址解释为对象

visual-studio - 如何让 Visual Studio 进入第三方程序集

visual-studio - C# 如何使用 IEnumerator 创建通用列表集合

c++ - 我的 bool 函数一直返回 true,我不确定为什么

sql-server - 如何将 .sql 文件导入 SQL Server Express

windows - TB_SETPADDING 消息对垂直填充没有影响