首页 > 解决方案 > Windows C 运行时 _close(fd) 未关闭文件

问题描述

我们在使用 C 和 C++ 混合编写的 Windows 应用程序的生产中遇到问题,其中 MoveFileEx 偶尔报告“该进程无法访问该文件,因为它正被另一个进程使用。”。该问题很少见,但最近我们已经能够在我们的开发环境中重现该问题。发生的情况是进程 A 通过网络接收数据并使用该数据创建一个文件:

fd = _open(fileName, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, _S_IREAD | _S_IWRITE);
...
while (data on network) {
    write(fd, buffer, count);
}
...
int close_result = _close(fd);

在此过程 A 之后打开文件进行读取并再次关闭它。然后进程 A 在不退出的情况下创建进程 B。在负载非常高的情况下,A 中有许多线程,许多 B 进程并行处理,每个进程处理数百 MB,进程 B 有时会遇到 MoveFileEx 问题。当我运行进程监视器来捕获文件系统活动时,我可以看到当我们遇到问题时,调用了上述 _close(fd) 并且没有返回错误,但是进程监视器没有从进程 A 为该 _close(fd 注册任何 CloseFile 操作) 称呼。似乎 _close(fd) 调用没有到达操作系统。有没有人遇到过这样的问题?有什么想法可以尝试解决这个问题吗?我曾尝试使用 fopen 而不是 _open 和不同类型的刷新调用,但似乎没有任何帮助。

标签: cwindowsfile-handling

解决方案


值得注意的是,如果您在所有其他标志之外fopen()指定标志,Microsoft 的实现也支持文件非继承。N本质上它在_O_NOINHERIT内部传递给_open.

这是有人想在 C 运行时中使用缓冲 I/O 的情况,例如fwrite,fputs等(而不是_open/ write/ _close)。我花了几个小时研究后添加了这个注释,所以我认为它可能值得放在这里供某人参考。


推荐阅读