別のプロセスがファイルの内容を書き換えている間に、ファイルを読み取る (cat) とします。出力は予測可能でしょうか? 何が起こるでしょうか?
答え1
それは作家が何をするかによります。
ライターが既存のファイルを上書きする場合、ライターがリーダーを追い越したときに、リーダーは新しいコンテンツを見ることになります (追い越した場合)。ライターとリーダーの速度が異なる場合、リーダーは古いコンテンツと新しいコンテンツを交互に見ることがあります。
書き込み側が書き込みを開始する前にファイルを切り捨てると、その時点でリーダーはファイルの末尾まで実行します。
ライターが新しいファイルを作成し、その新しいファイルを古い名前に移動すると、リーダーは古いファイルから読み取りを続けます。開いているファイルが移動または削除されると、そのファイルを開いているプロセスは同じファイルから読み取りを続けます。ファイルが削除されると、最後のプロセスがファイルを閉じるまで、実際にはディスク上に残ります (ただし、再度開く方法はありません)。
Unixシステムでは、必須のロックアプリケーションが書き込みコンポーネントと読み取りコンポーネントが互いに干渉しないようにしたい場合は、開発者が適切なロックを使用する必要があります。カーネルによって開かれたファイルがユーザーアプリケーションによる書き込みから保護される例外がいくつかあります。たとえば、ループマウントされたファイルシステム イメージ、または一部の UNIX バリアント上で実行されている実行可能ファイル。
答え2
これは典型的な競合状態なので、結果は定義上予測できません。
とりわけ、それは
fopen(3)
またはopen(2)
書き込みモード、- ライターが出力をバッファリングしているかどうか、
- 読者がファイルをどのように読んでいるか、
- リーダーとライターの速度差、
- 読み取りと書き込みの開始の間の時間差。
- そしてもちろん、最新のマルチコア マシンでは、下位の他の要因 (プロセス スケジューリングなど) によって状況はさらに複雑になります。
ファイルの書き換え中にそのファイルを読み取る必要がある場合は、ライターにファイルの一時的なコピーを作成させ、それを変更してから元のファイルにコピーし直すことができます。rsync
たとえば、次の方法でこれを実行します。これを実装する方法はいくつかありますが、すべては無料ではありません。各方法にはそれぞれ欠点と影響があります。
答え3
以前の回答者はこれよりも包括的な説明をしていますが、彼が望んでいることをほぼ正確に実行できる、間違いなく機能するトリックがここにあります。
$ tail -f <filename>
書き込み中のファイルの末尾を表示します。たとえば、STDERR をファイルにパイプしながら別のターミナル ウィンドウで表示したい場合に便利です。