Gil*_*ili 6 windows winapi serial-port iocp io-completion-ports
我拉着我的头发试图找出一个串口何时完成关闭所以我可以重新打开它.事实证明,CloseHandle()在端口实际解锁之前返回.
我使用打开一个串行端口CreateFile(FILE_FLAG_OVERLAPPED),使用它与一个完成端口关联CreateIoCompletionPort(),读/写使用它ReadFile(),WriteFile()并用关闭它CloseHandle().
我注意到如果我快速关闭并重新打开一个串口,我就会ERROR_ACCESS_DENIED回来CreateFile().尽管我正在等待CloseHandle()返回,然后等待与该句柄相关的所有未完成的读/写操作从完成端口返回,但这种情况正在发生.肯定有更好的方法:)
如何同步关闭串口?请不要重试循环,睡眠()或其他一些廉价的黑客攻击.
编辑:也许这与我使用完成端口和FILE_FLAG_OVERLAPPED有关.当读/写操作完成时,我得到一个回调.端口关闭是否有某种回调?
我认为问题出在为 COM 端口提供服务的驱动程序上。因此,不会有 API 来“实际关闭”COM 端口。
顺便说一句,关闭文件句柄后,无需等待所有未完成的 I/O 完成但出现错误。当CloseHandle返回时,所有未完成的 I/O 都已完成/取消,您只需异步接收回调(无论是通过完成端口还是 APC 队列)。
特别是 FTDI 驱动程序(那些模拟 COM->USB 的驱动程序)众所周知非常容易出现故障。
我可能只建议在关闭句柄之前尝试刷新数据。您可以等待所有 I/O 完成后再关闭 COM 端口(如果这适用于您的情况)。或者,您可以致电SetCommMask并WaitCommEvent确保没有待发送的数据。希望这会有所帮助。
编辑:
是否CloseHandle立即(在返回之前)取消文件句柄上所有挂起的 I/O?
严格来说——不。
可能还存在对该文件对象的其他引用。例如,用户模式代码可以调用DuplicateHandle,或者内核模式驱动程序可以调用ObReferenceObjectByXXXX。在这种情况下,句柄所引用的对象不一定被释放。
当最后一个句柄关闭时,DispatchCleanup将调用驱动程序。它必须根据此取消所有未完成的 I/O 。
然而,当一个线程在 a 中时CloseHandle,理论上您可以从另一个线程发出另一个 I/O(如果幸运的话,句柄仍然有效)。当您调用 I/O 函数(例如WriteFile或 等)时,操作系统会暂时增加对象的引用计数器。这反过来可能会启动另一个 I/O,该 I/O 不会被调用直接取消CloseHandle。
然而,在这种情况下,在发出新的 I/O 后,操作系统将立即关闭句柄,因为对象的引用计数再次达到 0。
因此,在这种变态的情况下,可能会发生这样的情况:在调用后立即CloseHandle无法再次重新打开文件。
| 归档时间: |
|
| 查看次数: |
4909 次 |
| 最近记录: |