c++ - 子进程中的间歇性文件访问错误

标签 c++ file-io

我正在开发一种编译器启动器,其基本操作顺序如下:

  1. 通过网络连接接受一批源文件,并将它们写入本地文件系统的目录。
  2. 对这些文件执行多次编译器启动(作为子进程)。
  3. 收集编译器生成的文件并将它们发回。
  4. (可选)清理。

虽然编译器启动是并行的,但第 1、2、3、4 步是严格按顺序执行的,不会重叠。

问题是,在 Windows Server 2008 R2 Enterprise 上,编译器会间歇性地提示某些文件丢失或权限被拒绝,例如。例如:

some_file1.h(20) : fatal error C1083: Cannot open include file: 'some_file1.h': No such file or directory

或:

c1xx : fatal error C1083: Cannot open source file: 'some_file3.cpp': Permission denied

通常,与给定文件有关的故障会在多次编译器启动时重复出现。我从未在开发机器上遇到过这些故障。

编译器提示的所有文件在我事后检查时实际上并不存在。我还保存了编译器启动的完整日志,包括命令行、启动目录和环境变量。当我手动重新运行它们时,它们运行良好。

这一切看起来像是操作系统对文件系统数据进行了一些缓存,使得并非所有最新数据始终对其他进程(包括子进程)可用。

写入文件的代码如下所示:

bool Session::receive_file(
    unsigned long long file_size,
    std::string const& full_path)
{
    std::ofstream ofs(full_path, std::ios::binary | std::ios::trunc);

    if (!ofs)
    {
        skip_input(file_size);
        return false;
    }

    char buf[4096];

    while (file_size)
    {
        std::streamsize s = sizeof buf;
        if (static_cast<unsigned long long>(s) > file_size)
            s = file_size;

        read_buffer(buf, s);

        file_size -= s;

        if (!(ofs.write(buf, s)))
        {
            skip_input(file_size);
            return false;
        }
    }

    ofs.close();

    if (!ofs)
        return false;

    return true;
}

我尝试用 fopen/fwrite/fcloseCreateFile/WriteFile< 重新实现它/CloseHandle 但无济于事。

我还尝试在此函数的末尾打开新写入的文件以供阅读,希望它能让操作系统恢复正常或有助于诊断文件访问问题。没有改变;我自己的进程总是打开并成功读取文件,但子进程仍然遇到间歇性故障。

在生成编译器之前插入 250 毫秒的延迟似乎可以显着降低错误的频率,但并不能完全消除它们(无论如何 250 毫秒太过分了,因为我必须处理交互式请求)。

我在清理步骤中也遇到了类似的问题:删除编译器生成的文件时,出现“文件正在使用”错误。然而,这对我来说不是那么重要。

我不敢相信我正在做的事情是独一无二的。实际上,我现在正在用 C++ 重新实现一个最初用 Perl 编写的服务器。 Perl 版本遇到了某些稳定性问题——但不是这个特殊问题。这意味着有多种方法可以使文件系统和子进程保持同步。

一定是我做错了什么。这是什么?

最佳答案

this 中所述MSDN 文章,文件读写一般由操作系统缓存。可以通过将 FILE_FLAG_NO_BUFFERING 参数传递给 CreateFile 来关闭缓存。方法。

如果无法访问文件创建过程,可以通过调用 FlushFileBuffers 告诉操作系统刷新特定文件的文件缓存。 .

关于c++ - 子进程中的间歇性文件访问错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425407/

相关文章:

c++ - 三路运算符 <=> 返回带有隐式转换函数的结构体

c++ - 将文本文件中的字符串和整数输入变量

对不同文件模式的混淆

java - 写入字节数组时出现 IOException

java - 在 Java 中使用 BufferedReader 一个接一个地读取不同的文件

c++ - Qt LanguageChange 事件 - 找出新的语言

c++ - 旋转数组 :Segmentation Fault (SIGSEGV)

python - 继续写入文件的同一行

c++ - 是否可以动态地将函数分配给函数指针?

c++ - Rand() 是生成器,即使我调用了 srand(time(NULL))