gpt4 book ai didi

windows - CloseHandle() 在串口实际关闭之前返回

转载 作者:可可西里 更新时间:2023-11-01 13:27:25 27 4
gpt4 key购买 nike

我绞尽脑汁想弄清楚串行端口何时完成关闭,以便我可以重新打开它。事实证明,CloseHandle() 在端口实际解锁之前返回。

我正在使用 CreateFile(FILE_FLAG_OVERLAPPED) 打开一个串行端口,使用 CreateIoCompletionPort() 将其与 CompletionPort 相关联,使用 ReadFile( )WriteFile() 并使用 CloseHandle() 关闭它。

我注意到,如果我足够快地关闭并重新打开串行端口,我会从 CreateFile() 返回一个 ERROR_ACCESS_DENIED。尽管我正在等待 CloseHandle() 返回,然后等待与该句柄关联的所有未完成读/写操作从完成端口返回,但这种情况仍在发生。当然有更好的方法:)

如何同步关闭串行端口?请不要重试循环、sleep() 或其他一些廉价的技巧。

编辑:也许这与我使用完成端口和 FILE_FLAG_OVERLAPPED 有关。当读/写操作完成时,我得到一个回调。端口关闭是否有某种回调?

最佳答案

我认为问题出在服务于 COM 端口的驱动程序上。因此 - 将没有 API 来“实际关闭”COM 端口。

顺便说一句,关闭文件句柄后,无需等待所有未完成的 I/O 完成并出现错误。当 CloseHandle 返回时,所有未完成的 I/O 都已经完成/取消,您只需异步接收回调(无论是通过完成端口还是 APC 队列)。

特别是 FTDI 驱动程序(那些模拟 COM->USB 的驱动程序)众所周知是非常有问题的。

我可能只建议在关闭句柄之前尝试刷新数据。您可以等待所有 I/O 完成然后关闭 COM 端口(如果这适用于您的情况)。或者,您可以调用 SetCommMaskWaitCommEvent 以确保没有待处理的发送数据。希望这可能有所帮助。

编辑:

CloseHandle 是否会立即(在返回之前)取消文件句柄上所有未决的 I/O?

严格来说 -

可能还有其他对文件对象的引用。例如,用户模式代码可以调用 DuplicateHandle,或者内核模式驱动程序可以调用 ObReferenceObjectByXXXX。在这种情况下,句柄所指的对象不一定会被释放。

当最后一个句柄关闭时,将调用驱动程序的 DispatchCleanup。它必须根据 this 取消所有未完成的 I/O。 .

然而,当一个线程在 CloseHandle 中时 - 理论上您可以从另一个线程发出另一个 I/O(如果幸运的话 - 句柄仍然有效)。当您调用 I/O 函数(例如 WriteFile 等)时,操作系统会暂时增加对象的引用计数器。这反过来可能会启动另一个 I/O,它不会被 CloseHandle 调用直接取消。

然而在这种情况下,句柄将在发出新的 I/O 后立即被 O/S 关闭,因为对象的引用计数再次达到 0。

因此在这种变态的情况下,可能会发生这样的情况,即在调用 CloseHandle 之后您无法再次重新打开文件。

关于windows - CloseHandle() 在串口实际关闭之前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8885748/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com