問題タブ [fsync]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
python - サブプロセス呼び出しからリダイレクトされた出力が失われましたか?
あなたが持っているかもしれないし持っていないかもしれないいくつかのライブラリを使って、私は大まかにこのようなPythonコードをいくつか持っています:
基本的に、データをダウンロードして標準出力に出力するサブプロセスを開始しています。そのデータをファイルにリダイレクトし、サブプロセス呼び出しが戻るとすぐに、ファイルへのハンドルを閉じて、ファイルを別の場所にコピーします。
私が期待しているデータの最後尾がコピーに含まれていない場合があることを観察しています。今、時々そのデータを書き込んでいない可能性がありますが、安全でないことをしていて、が戻った後、子プロセスが標準出力に書き込むデータが作成される前にbcftools
、何らかの方法でファイルにアクセスできるのではないかと心配しています。私が見ることができるディスクに。subprocess.check_call()
C 標準を見ると (bcftools は C/C++ で実装されているため)、プログラムが正常に終了すると、開いているすべてのストリーム (標準出力を含む) がフラッシュされて閉じられるように見えます。戻り時に暗黙的に呼び出されるの動作について説明している、こちら[lib.support.start.term]
のセクションを参照してください。exit()
main()
--次に、未書き込みのバッファリングされたデータを含むすべての開いている C ストリーム (で宣言されている関数シグネチャによって仲介される) がフラッシュされ、開いているすべての C ストリームが閉じられ、tmp-file() の呼び出しによって作成されたすべてのファイルが削除されます.30)
-- 最後に、制御がホスト環境に戻されます。status が 0 または EXIT_SUCCESS の場合、成功した終了ステータスの実装定義形式が返されます。ステータスが EXIT_FAILURE の場合、ステータスの失敗した終了の実装定義形式が返されます。それ以外の場合、返されるステータスは実装定義です.31)
したがって、子プロセスが終了する前に、標準出力を閉じます (したがって、フラッシュします)。
ただし、Linuxのマニュアル ページclose(2)
では、ファイル記述子を閉じても、それに書き込まれたデータが実際にディスクに書き込まれたことを必ずしも保証しないことに注意してください。
カーネルが書き込みを遅延させるため、クローズが成功しても、データがディスクに正常に保存されたことは保証されません。ストリームが閉じられたときにファイルシステムがバッファをフラッシュすることは一般的ではありません。データが物理的に保存されていることを確認する必要がある場合は、fsync(2) を使用してください。(この時点では、ディスク ハードウェアによって異なります。)
したがって、プロセスが終了すると、その標準出力ストリームがフラッシュされるように見えますが、そのストリームがディスク上のファイルを指すファイル記述子によって実際にバックアップされている場合、ディスクへの書き込みが完了したとは限りません。それがここで起こっていることかもしれないと思います。
だから、私の実際の質問:
私の仕様の読みは正しいですか?リダイレクトされた標準出力がディスク上で利用可能になる前に、子プロセスが親に終了したように見えることがありますか?
子プロセスによってファイルに書き込まれたすべてのデータが実際に OS によってディスクに同期されるまで、何らかの方法で待機することは可能ですか?
親プロセスのファイルオブジェクトのコピーで、
flush()
またはPythonバージョンを呼び出す必要がありますか?fsync()
子プロセスによる同じファイル記述子への書き込みを強制的にディスクにコミットできますか?
linux - Linux fsync はファイルの xattr を同期しますか?
man fsync(2) から、ファイルのメタデータを同期します。これは、統計のリストにあると思います。ファイルの xattr はどうですか? それはメタデータに属していますか?テストを行い、ファイルを作成し、6 つの xattrs を設定し、次に fsync を実行し、次に 1 つの xattr 値を変更して、再度 fsync を実行します (0.2 秒を使用)。2 番目の fsync は高速である必要があると考えていますが、そうではありません (0.16 秒を使用)。
c - ファイル記述子を閉じるときにデータの損失を防ぐ方法は?
を発行するwrite()
と、データがいくつかのカーネル空間バッファーに移動します。物理層への実際のコミット (「phy-commit」) は、(おそらく) まで延期されます.. (正確には、どのイベントまで?)
close()
ファイル記述子に対してを発行すると、
[...] の場合、開いているファイルの説明に関連付けられているリソースが解放されます
データが含まれていたカーネル バッファを解放 (解放) するということですか? それらのバッファに含まれる貴重なデータはどうなりますか? 失うだろう?
その損失を防ぐには?
経由fsync()
?明示的な phy-commit を要求します。すぐに(同期呼び出し)、または「短時間」だけ延期し、後続の操作、少なくとも破壊的な操作の前にキューに入れたと思います。
しかし、私は即時または緊急のphy-commitを望んでいません。(データを保持し、)後でphy-commitを行うことを忘れないでください。
からman fclose
:
fclose() 関数 [...] は、基になるファイル記述子を閉じます。
...
fclose() は、C ライブラリによって提供されるユーザー空間バッファーのみをフラッシュします。データが物理的にディスクに保存されるようにするには、たとえば sync(2) または fsync(2) を使用して、カーネル バッファーもフラッシュする必要があります。
が先行するfsync
必要はない(またはを含む)ことを示唆している可能性がありますが、後続することはできます (しなければならないことさえあります)。したがって、非常に破壊的ではありません... close
fclose
close
close()