我利用各种来源拼凑了一些(多线程)代码来从串行端口读取和写入。一切都工作正常......除了从串行端口读取的线程中的循环无意中进行了繁忙的等待。本质上重复发生的是:
- 事件(在读取循环之外创建)被重置,并且其句柄用作 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.
}