上書きされているファイルを読み取るとどうなりますか?


26

別のプロセスがその内容を書き換えている間に、ファイルを読み取る(cat)と仮定します。出力は予測可能ですか?どうなるの?


3
動作は未定義です。これは絶対にしないでください。
デイジー

回答:


19

それは作家が何をするかによります。

ライターが既存のファイルを上書きする場合、ライターがリーダーを追い越した場合、リーダーは新しいコンテンツを表示します。ライターとリーダーが可変速度で進む場合、リーダーは代わりに古いコンテンツと新しいコンテンツを見ることができます。

ライターが書き込みを開始する前にファイルを切り捨てた場合、リーダーはその時点でファイルの終わりに対して実行されます。

ライターが新しいファイルを作成し、新しいファイルを古い名前に移動すると、リーダーは古いファイルから読み取りを続けます。開いているファイルが移動または削除された場合、そのファイルを開いているプロセスは、同じファイルから読み取りを続けます。ファイルが削除された場合、最後のプロセスによってファイルが閉じられるまで、実際にはディスクに残ります(ただし、再度開く方法はありません)。

Unixシステムは、強制ロックを持たない傾向があります。アプリケーションがライターコンポーネントとリーダーコンポーネントが互いのつま先を踏まないようにしたい場合、適切なロックを使用するのは開発者の責任です。カーネルによって開かれているファイルがユーザーアプリケーションによる書き込みから保護される可能性があるいくつかの例外があります。たとえば、ループにマウントされたファイルシステムイメージや、一部のUNIXバリアントで実行される実行可能ファイルです。


ジル、あなたの説明はftp/ sftpシナリオにも当てはまりますか?ftp同じファイルの別のバージョンが新しい送信のために上書きしている間に、プロセスが送信されたファイルの読み取りを開始するとします。
iruvar

@ 1_CRはい。その場合、ライターとリーダーはftpdプロセスです。
ジル「SO-悪であるのをやめる」14

ここで追い越しの意味は何ですか?
ビクターチョイ

@VictorChoy標準的な意味:他の誰かの後ろ/後ろから開始し、ある時点で先に進むこと。
ジル「SO-悪であるのをやめる」

18

これは古典的な競合状態であるため、結果は定義上予測できません。

とりわけ、それはに依存します

  • fopen(3)またはopen(2)書き込みモード、
  • ライターが出力をバッファリングする方法/場合、
  • リーダーがファイルをどのように読んでいるか、
  • リーダーとライターの速度の違い、
  • 読み取りとライターの開始の時間差。
  • そしてもちろん、最新のマルチコアマシンでは、他の要因(プロセススケジューリングなど)によってさらに複雑になります。

書き換え中にファイルを読み取れるようにする必要がある場合は、ライターにファイルの一時コピーを作成させ、それを変更してから元のファイルにコピーして戻すことができます。これはrsync、たとえばこれを行います。これを実装する方法はいくつかありますが、無料のランチはありません。各方法には独自の欠点と影響があります。


1
この答えは私の答えよりもはるかに包括的なものです。回答を削除します。
キラーミスト

0

以前のレスポンダーにはこれよりも包括的な説明がありますが、間違いなくうまく機能するトリックがあります。

$ tail -f <filename>

書き込み中にファイルの終わりを表示します。たとえば、STDERRをファイルにパイプしたいが、それでも別のターミナルウィンドウで表示したい場合に便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.