异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件?

2024-01-05

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

  • 事件(在读取循环之外创建)被重置,并且其句柄用作 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 成员的零值相结合,指定读取操作将立即返回已接收到的字节,即使尚未接收到任何字节。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件? 的相关文章

随机推荐

  • .NET Core 应用程序进程内存在对象被释放后不会减少

    我在 Windows 中运行的 ASP NET Core 2 1 应用程序遇到问题 该应用程序增加了内存消耗 直到最终崩溃并需要终止 NET Core Host过程 我怀疑原因可能是每小时在后台运行一次的同步任务 并且我已确认禁用它可以解决
  • 数据访问层的设计模式

    我有一个使用数据库 MongoDB 来存储信息的应用程序 过去 我使用了一个充满静态方法的类来保存和检索数据 但后来我意识到这不是非常面向对象或面向未来的 尽管我不太可能更改数据库 但我宁愿拥有一些不会将我与 MongoDB 联系得太紧密的
  • javafx2 中的菜单项工具提示

    javafx2中有两个问题 如何为菜单项设置工具提示 如何设置菜单项的大小 宽度 如果您有答案 请告诉我 这两个问题的答案都直接向全班同学提供自定义菜单项 http docs oracle com javafx 2 api javafx s
  • FreeLibraryAndExitThread 在卸载注入的 DLL 时导致程序崩溃

    我正在编写一个 DLL 它被注入到游戏中 以便进行一些逆向工程 有一段时间 当我对程序进行更改时 我能够成功地注入 弹出和重新注入 我在用着FreeLibraryAndExitThread卸载 将 XInput 添加到程序中以便我可以捕获用
  • Java练习:使用递归方法打印星号三角形及其倒三角形

    我需要打印一个三角形及其倒三角形 站在其尖端 我设法只打印出三角形 我知道我可以轻松使用 for 循环 但我想知道如何使用递归 就我而言 我不知道如何打印三角形和倒三角形 谢谢 Example desired output My code
  • ASP.NET MVC - 视图模型、域模型和数据模型[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用样本函数将数据拆分为训练/测试集

    我刚刚开始使用 R 我不确定如何将我的数据集与以下示例代码合并 sample x size replace FALSE prob NULL 我有一个数据集 需要将其放入训练集 75 和测试集 25 中 我不确定应该在 x 和 size 中输
  • 防止方法上的 JIT 内联

    我的情况比较特殊 我一直在开发一个用于发送电子邮件的开源库 在这个库中 我需要一种可靠的方法来获取调用方法 我已经用一个完成了这个StackTrace通过分析StackFrame里面的物体 这在关闭优化的调试模式项目中没有问题 当我切换到打
  • 在 Struts 2 中使用 UrlRewrite 设置参数变量

    我在用着塔基网址重写 http www tuckey org urlrewrite 与 Struts2 应用程序结合使用 我正在尝试转换以下网址 promotions abcdef 987 to dopromotions detail传递变
  • Java中如何检查String值是否为Boolean类型?

    我对此做了一些搜索 但找不到任何有用的东西 要点是 如果 String 值是 true 或 false 则返回值应该是 true 在所有其他值中它都应该是假的 我尝试过这些 String value false System out pri
  • 如何使用正则表达式(Regex)从字符串中获取电话号码?

    我想要正则表达式 它通过忽略空格 加号 括号和破折号来找出连续的最大 12 位数字 例如 Primary contact number 91 98333332343 call me on this My number is 91 983 3
  • 如何使两个相关但独立的系统保持同步?

    我当前的开发项目有两个方面 首先 有一个公共网站 外部用户可以出于各种目的提交和更新信息 然后 此信息将保存到托管设施的本地 SQL Server 中 第二个方面是内部应用程序 员工使用它来管理这些相同的记录 概念上 并提供状态更新 批准等
  • Safari 中的 Ogg 音频

    如何在 safari 中播放 ogg 音频文件而不将其转换为 mp3 我用媒体元素 js http www mediaelementjs com 库到 flash 后备 它在 chrome 和 firefox 中工作正常 可以播放 mp3
  • 如何使这个 R 包的输出静音?

    我正在玩一点LowRankQP 在R中打包 甚至设置verbose FALSE仍然产生大量输出 参见下面的示例 输出来自代码的编译部分 R 中有没有一种方法 包装函数 来调用LowRankQP 绝对安静 即不在上面打印任何内容 screen
  • 如何在 Laravel 查询的 WHERE 子句中使用正则表达式?

    我有一个名为 Shows 的表 有一个列 show date 我想检索 show date 是今天日期的节目 以下是我的查询 s DB table shows gt get a DB table shows gt select show d
  • 如何使用selenium python获取伪元素的css值?

    我的页面有 html div class bar title before div 选择 Chrome 或 Firefox before我可以在 样式 选项卡上看到 css SomeTitle bar before content requ
  • 预期换行符为“LF”,但发现换行符为“CRLF”样式

    在 gulp 项目中使用 eslint 时 我遇到了这样的错误问题 Expected linebreaks to be LF but found CRLF linebreak style我正在使用 Windows 环境运行 gulp 下面给
  • “干净代码”的定义[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 罗伯特 C 马丁在他的书的第一章中提出 干净的代码 https rads stackoverflow com amzn click com 01
  • 作曲家自签名证书

    更新到最新版本的作曲家 多年来 我们一直在 http 上托管我们的包存储库 没有出现任何问题 但现在 Composer 说它需要通过 https 连接 我可以通过放置来解决这个问题 secure http false 在我的composer
  • 异步串行通信:为什么 ReadFile() 在 OVERLAPPED 结构中设置事件?

    我利用各种来源拼凑了一些 多线程 代码来从串行端口读取和写入 一切都工作正常 除了从串行端口读取的线程中的循环无意中进行了繁忙的等待 本质上重复发生的是 事件 在读取循环之外创建 被重置 并且其句柄用作 OVERLAPPED 结构中的 hE