簡體   English   中英

子進程中的間歇性文件訪問錯誤

[英]Intermittent file access errors in child processes

我正在開發一種編譯器啟動器,其基本操作順序如下:

  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 ms的延遲似乎會嚴重降低錯誤的發生率,但並不能完全消除錯誤(無論如何,由於我必須處理交互式請求,所以250 ms實在是太糟糕了)。

我在清理步驟中也遇到了類似的麻煩:刪除編譯器生成的文件時,出現“文件正在使用”錯誤。 但是,這對我來說沒有那么重要。

我無法相信這是我正在做的獨特事情。 實際上,我現在正在用C ++重新實現最初用Perl編寫的服務器。 Perl版本遇到某些穩定性問題,但沒有遇到此特定問題。 這意味着有多種方法可以使文件系統和子進程保持同步。

我一定做錯了。 它是什么?

如此 MSDN文章中所述,文件讀取和寫入通常由操作系統緩存。 可以通過將FILE_FLAG_NO_BUFFERING參數傳遞給CreateFile方法來關閉緩存。

如果沒有訪問文件創建過程的權限,則可以通過調用FlushFileBuffers告訴操作系統為特定文件刷新文件緩存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM