職場では、Jenkins の助けを借りて、複数のビルド マシンでユニット テストを定期的に実行しています。単体テストの 1 つは、でファイルを開き、このファイルFILE_FLAG_WRITE_THROUGH
に対して何万回ものWriteFile
呼び出しを行います。なぜそうするのかは、この質問には関係ありません。ビルド マシンの 1 つだけで、このテストは常にタイムアウトしていました。いくつかの調査の後、これの根本的な原因は、 への各呼び出しWriteFile
がブロックされ (スレッドが切り替えられ、後で切り替えられた)、テストの実行が大幅に遅くなったことであることが判明しました。不思議なことに、このマシンでテストを手動で開始したとき、WriteFile
はブロックされなかったため、テストはタイムアウトしませんでした。
何時間もの試行錯誤の後、「回避策」を見つけました。影響を受けるマシンで、Jenkins がタスク スケジューラで起動WriteFile
された場合、ブロックされました。手動で起動した場合、またはスタートアップ フォルダーに BAT ファイルを配置して起動した場合は、そうではありませんでした。もっと調査する必要があると思ったので、最小限の再現、ファイルを で開き、ランダムなデータで 10000 回FILE_FLAG_WRITE_THROUGH
呼び出す小さなプログラムを作成しました。WriteFile
この最小限の再現では、WriteFile
起動方法に関係なく、常にブロックされます。私は本当に混乱しているので、ここでこの動作の説明を求めています。テストを実行したすべてのマシンには、デフォルト設定 (書き込みキャッシュと Windows 書き込みキャッシュ フラッシュが有効) の SATA ドライブが搭載されていました。
まず第一に、何FILE_FLAG_WRITE_THROUGH
をすべきかは 100% 明確ではありません。インターネット上の情報によると、特別なフラグがデバイスに渡され、書き込み後にキャッシュをフラッシュするように求められます。Raymond Chen (および他の多くの人々) によると、パフォーマンス上の理由から、大多数の SATA ドライブがこのフラグを黙って無視するため、これは今日ではほとんど無関係です。「ブロックすべきか、すべきでないか」の側面では、このページはブロックFILE_FLAG_WRITE_THROUGH
WriteFile
すべきであると明確に述べています。
データがファイルに書き込まれるまで、書き込み呼び出しは戻りません。
この奇妙な動作が (一貫性なく) 見られる理由について何か考えはありますか? どうすればさらに調査できますか?