【问题标题】:What if I call CloseHandle(h) before an asynchronous read on handle h has not finished?如果我在对句柄 h 的异步读取尚未完成之前调用 CloseHandle(h) 会怎样?
【发布时间】:2013-02-08 05:47:41
【问题描述】:

考虑以下场景:

auto h = CreateFile(...);
ReadFileEx(h, ...); // Asynchronous read for a large block of data. say, 1GB.
CloseHandle(h); 
// If the read has not yet finished here, what will happen? Big Bang???

【问题讨论】:

  • @Alok,你能推荐我到具体的 MSDN 页面吗?
  • 如果可以的话,尝试使用C89标准中描述的文件管理功能linux.die.net/man/3/fopenlinux.die.net/man/3/fclose
  • 另外,您可以告诉操作系统使用 mmap 为您执行异步读取,并将文件直接映射到内存。 (对于一些指针,请参阅linuxquestions.org/questions/programming-9/…
  • @xmllmx:这是我最好的猜测。我找不到任何明确说明的参考资料。
  • 从事这种冒险行为的动机是什么?这不正是为什么ReadFileEx 函数的最后一个参数允许您指定一个指向在操作完成时调用的函数的指针吗?在那里拨打CloseHandle

标签: c windows exception file-io asynchronous


【解决方案1】:

只要 Asyncronous 句柄在调用时有效,异步操作在完成之前将保持有效。这是因为异步文件 IO 调用包含对内核中文件对象的隐式引用计数。

当异步事件完成时,如果用户模式下没有更多句柄指向该文件,则该文件将在内核内部关闭。

请注意,这确实有明显的副作用。特别是,如果您打开文件以进行独占读/写,发出异步操作然后关闭句柄,则在异步操作完成之前,该文件将无法打开以进行读/写。

【讨论】:

  • 我刚刚测量了这个问题:我写了一些代码,首先是一个 CancelIo 来取消所有未完成的 I/O 操作,然后是一个 CloseHandle。 CancelIo 持续大约 15 毫秒 - 使用 GetSystemTimeAsFiletime 测量 - 之后的 CloseHandle 无法准确测量,即它花了 0 毫秒。当我删除 CancelIo CloseHandle 时,CPU 时间为 15 毫秒。所以看起来 CloseHandle 隐式取消了未完成的 I/O 请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
相关资源
最近更新 更多