アプリケーションに内部キャッシュがない場合、変更はすぐにファイルに書き込まれます。あなたの例でも同じです。ファイルはメモリ内の論理エンティティであり、すぐに更新されます。ファイルに対する後続の操作では、プログラムによって行われた変更が表示されます。
ただし 、これは変更が物理ディスクに書き込まれたことを意味するものではありません。変更は、OS ファイルシステム キャッシュまたはハードウェア キャッシュに残る可能性があります。ファイルシステム バッファをフラッシュするには、sync
を使用します。 コマンド。
コマンド終了直後にファイルを読みたいのですが、空のファイルは読みたくありません。
ここで実用的な問題に遭遇するべきではありません。
関連するバッファ/キャッシュの複数の層があります。
<オール>CPU キャッシュ。
データはバイトごとにまとめられ、CPU キャッシュに格納されます。 CPU キャッシュがいっぱいで、データがしばらくアクセスされていない場合、データを含むブロックがメイン メモリに書き込まれる可能性があります。これらは、ほとんどの場合、アプリケーション プログラマーには隠されています。
インプロセス バッファ。
データが収集されるプロセスでメモリが確保されるため、OS への要求をできるだけ少なくする必要があります。これは比較的コストがかかるためです。プロセスはデータをこれらのバッファにコピーしますが、これも CPU キャッシュによってバックアップされる可能性があるため、データがメイン メモリにコピーされるという保証はありません。アプリケーションは、たとえば fclose(3) または fsync(3) を使用して、これらのバッファを明示的にフラッシュする必要があります。 exit(3) 関数も、プロセスが終了する前にこれを行いますが、_exit(2) 関数はしません 、これが、その関数のマニュアルページに、自分が何をしているのかを知っている場合にのみ呼び出すようにという大きな警告がある理由です.
カーネルバッファ
その後、OS は独自のキャッシュを保持して、ディスクに送信する必要がある要求の数を最小限に抑えます。このキャッシュは特にプロセスに属していないため、そこにあるデータは既に終了したプロセスに属している可能性があり、すべてのアクセスはここを通過するため、次のプログラムはここに到達したデータを参照します。カーネルは、時間があるとき、または明示的に要求されたときに、このデータをディスクに書き込みます。
ドライブキャッシュ
ディスクドライブ自体もキャッシュを保持してアクセスを高速化します。これらはかなり迅速に書き込まれ、残りのデータをキャッシュに書き込み、それが完了したときに報告するコマンドがあります。OS はシャットダウン時にこれを使用して、電源を切る前にデータが書き込まれていないことを確認します。
アプリケーションでは、データがカーネル バッファに登録されていれば十分です (実際のデータは、この時点でまだ CPU キャッシュに存在し、メイン メモリに書き込まれていない可能性があります)。「エコー」プロセスが終了し、これは、インプロセス バッファがフラッシュされ、データが OS に渡されている必要があることを意味します。新しいプロセスを開始すると、OS は要求されたときに同じデータを返すことが保証されます。
<ブロック引用>
プロセスが終了すると、バッファは自動的にディスクにフラッシュされますか?
一般的に、答えはいいえです .
コマンドによって異なります。他の回答が言及しているように、if コマンドはデータを内部的にバッファリングしません。コマンドが終了すると、すべてのデータが利用可能になります。
ただし、すべてではないにしても、ほとんどの標準 I/O ライブラリは行います。 デフォルトで stdout を (ある程度) バッファリングし、アプリケーションが閉じたときのバッファの自動フラッシュについてさまざまな保証を提供します。
C は、通常の終了でバッファーがフラッシュされることを保証します。 「正常終了」は exit
を意味します が呼び出されます — 明示的に、または main
から戻ることによって .ただし、異常終了により、この呼び出しが回避される可能性があります (したがって、フラッシュされていないバッファーが残ります)。
以下に簡単な例を示します:
#include <signal.h>
#include <stdio.h>
int main() {
printf("test");
raise(SIGABRT);
}
これをコンパイルして実行すると test
しません 必ず stdout に書き込まれます。
他のプログラミング言語では、さらに保証が少なくなります。たとえば、Java は保証しません。 プログラムの終了時に自動フラッシュします。出力バッファに終了していない行が含まれている場合、 System.out.flush()
でない限り、行が失われる可能性があります。 明示的に呼び出されました。
とはいえ、質問の本文は少し異なることを尋ねます。データがファイルにまったく到着した場合 、コマンドが終了した直後にそうする必要があります(他の回答で説明されている警告に従います)。