![](/img/trans.png)
[英]Intermittent, random 'file not found' errors under Windows Subsystem for Linux (WSL)
[英]Intermittent file access errors in child processes
我正在開發一種編譯器啟動器,其基本操作順序如下:
盡管編譯器啟動是並行的,但是步驟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
/ fclose
和CreateFile
/ WriteFile
/ CloseHandle
重新實現它,但無濟於事。
我還嘗試在此功能結尾處打開新編寫的文件以進行讀取,以希望它能使操作系統正常運行或有助於診斷文件訪問問題。 沒有改變; 我自己的進程始終打開並成功讀取文件,但是子進程仍然遇到間歇性故障。
在產生編譯器之前插入250 ms的延遲似乎會嚴重降低錯誤的發生率,但並不能完全消除錯誤(無論如何,由於我必須處理交互式請求,所以250 ms實在是太糟糕了)。
我在清理步驟中也遇到了類似的麻煩:刪除編譯器生成的文件時,出現“文件正在使用”錯誤。 但是,這對我來說沒有那么重要。
我無法相信這是我正在做的獨特事情。 實際上,我現在正在用C ++重新實現最初用Perl編寫的服務器。 Perl版本遇到某些穩定性問題,但沒有遇到此特定問題。 這意味着有多種方法可以使文件系統和子進程保持同步。
我一定做錯了。 它是什么?
如此 MSDN文章中所述,文件讀取和寫入通常由操作系統緩存。 可以通過將FILE_FLAG_NO_BUFFERING參數傳遞給CreateFile方法來關閉緩存。
如果沒有訪問文件創建過程的權限,則可以通過調用FlushFileBuffers告訴操作系統為特定文件刷新文件緩存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.