【问题标题】:Cancel WaitCommEvent for overlapped serial I/O取消重叠串行 I/O 的 WaitCommEvent
【发布时间】:2014-09-22 11:46:41
【问题描述】:

我正在通过串行端口以重叠方式处理非标准调制解调器。除了读取和写入电信线之外,我还必须使用WaitCommEvent()函数检查控制线,如CTSDSR

DWORD EvtMask;
/// (some scopes/levels ommitted)

const BOOL syncChange = WaitComEvent(hFile, &EvtMask, &overlapped);
if (!syncChange) {
    assert(GetLastError() == ERROR_IO_PENDING);
    /// *background activity* probably writing into EvtMask
    /// until overlapped.hEvent gets signalled
}

在(几乎所有)情况下,函数调用指示*background activity*,我必须等待overlapped.hEvent 发生。由于我也在等待来自其他来源的事件(例如由用户输入引起的 IPC、程序终止),因此我使用 WaitForMuiltipleObjects() 函数。但是,如果阻塞等待由于控制线更改以外的其他原因而完成,我该如何停止EvtMask 上的后台活动?我基于的代码目前使用SetCommMask(hFile, 0),但我没有找到合适的可靠参考。

我还观察到不正确支持对控制线进行更改的情况(驱动程序?虚拟机?),因此我必须进行切片等待并进行中间检查。

必须做什么才能安全地离开声明变量EvtMask的范围?

【问题讨论】:

  • 你必须调用 CancelIo()。当然,用户输入通常不是取消 I/O 的重要理由。你有一个中国幸运饼干,上面写着你要完全重写。
  • @HansPassant 哈哈,还有很多东西要重写...
  • @HansPassant 我改变了问题,还有另一个(重要的)原因需要考虑。现在对你来说更有意义了吗?谢谢!
  • @Hans:不,你没有。
  • @BenVoigt 所以这个问题在你看来是有效的?

标签: windows serial-port modem handshake overlapped-io


【解决方案1】:

您拥有的代码是正确的,并得到the documentation 的完全支持,其中明确表示:

如果一个进程在重叠的WaitCommEvent 操作正在进行时尝试使用SetCommMask 函数更改设备句柄的事件掩码,WaitCommEvent 将立即返回。

我在“真实”串行端口和 USB 虚拟串行端口仿真上都使用了这一事实,并且它工作可靠。

(在我的特殊情况下,我正在关注EV_TXEMPTY,以便我可以保证某些传输之间的最小间隔在电线上

【讨论】:

  • 很好,这部分我不清楚。它混合了 WaitCommEvent 调用和在后台启动的操作。不过,感谢您查看它。这绝对有帮助:-)
  • 一个小细节:用零掩码调用SetCommMask之后,你还要再调用WaitCommEvent吗?
  • @Wolf:待处理的WaitCommEvent 操作将立即完成(或者至少,很快——不要假设您在调用SetCommMask 后立即恢复了记忆)。因此,如果您想要再次通知,则必须再次调用它。
  • 如果我使用零掩码,那么可能不会有真正的通知。但似乎我在WaitCommEvent 调用中使用的变量仍然是绑定的。我不需要打电话给GetOverlappedResult(..., TRUE)吗?
  • @Wolf:您应该像处理其他任何事情一样处理强制完成。拨打GetOverlappedResult,如果您仍然对事件感兴趣,请再次拨打WaitCommEvent,否则您可以取消记忆。
猜你喜欢
  • 2013-02-04
  • 1970-01-01
  • 2010-09-08
  • 2011-12-04
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多