1

を発行するwrite()と、データがいくつかのカーネル空間バッファーに移動します。物理層への実際のコミット (「phy-commit」) は、(おそらく) まで延期されます.. (正確には、どのイベントまで?)

close()ファイル記述子に対してを発行すると、

[...] の場合、開いているファイルの説明に関連付けられているリソースが解放されます

データが含まれていたカーネル バッファを解放 (解放) するということですか? それらのバッファに含まれる貴重なデータはどうなりますか? 失うだろう?

その損失を防ぐには?

経由fsync()?明示的な phy-commit を要求します。すぐに(同期呼び出し)、または「短時間」だけ延期し、後続の操作、少なくとも破壊的な操作の前にキューに入れたと思います。

しかし、私は即時または緊急のphy-commitを望んでいません。(データを保持し、)後でphy-commitを行うことを忘れないでください。


からman fclose:

fclose() 関数 [...] は、基になるファイル記述子を閉じます。
...
fclose() は、C ライブラリによって提供されるユーザー空間バッファーのみをフラッシュします。データが物理的にディスクに保存されるようにするには、たとえば sync(2) または fsync(2) を使用して、カーネル バッファーもフラッシュする必要があります。

が先行するfsync必要はない(またはを含む)ことを示唆している可能性がありますが、後続することはできます (しなければならないことさえあります)。したがって、非常に破壊的ではありません... closefclosecloseclose()

4

1 に答える 1

1

データが含まれていたカーネル バッファを解放 (解放) するということですか? それらのバッファに含まれる貴重なデータはどうなりますか? 失うだろう?

いいえ。カーネル バッファーは、基になるファイルにデータを書き込む前に解放されません。そのため、データが失われることはありません (システムの停電など、何か本当に問題が発生しない限り)。そのデータがすぐに物理ファイルに書き込まれるかどうかは別の問題です。ファイルシステム(バッファリングしている可能性があります)および/またはハードウェアキャッシュにも依存している可能性があります。ユーザー プログラムに関する限り、close()呼び出しの成功は、ファイルへの書き込みの成功と見なすことができます。

fsync が close (または close を含む fclose) の前にある必要はありませんが、その後に来ることはできます (する必要さえあります)。したがって、 close() は非常に破壊的ではありません...

の呼び出し後、close()ファイル記述子の状態は POSIX によって未指定のままになります (close()成功したかどうかに関係なく)。そのため、呼び出しfsync(fd); に使用することはできませんclose()。参照: POSIX/UNIX: ファイル記述子を確実に閉じる方法.

close()いいえ、それは破壊的である可能性があることを示唆していません. これは、C ライブラリがユーザーで独自のバッファリングを行っている可能性があることを示唆しており、fsync()それをカーネルにフラッシュするために使用することを示唆しています (そして今、前に述べたのと同じ立場にあります)。

于 2016-11-21T16:58:41.330 に答える