0

非常に単純なコードで、一定の間隔で少量のデータをファイルに書き込むだけです。プログラムがファイルを作成してデータを追加した後、vim(またはその他のエディター)でこのファイルを開いて編集すると、プロセスがファイルを更新できなくなったようです。システムコールからエラーが返されることはありません。システムコールをトレースしてみましたが、ファイルが更新されていなくても奇妙なことは何も観察されませんでした。

各プロセスは現在のオフセットを持つ独自のファイルテーブルエントリを取得するため、私が期待していたのは、2つの非協調プロセス(おそらく文字化け)からの書き込みが散在するデータを含む出力ファイルでした。しかし、私が観察しているのは、他のエディターがファイルに書き込むと、プログラムがファイルを更新できなくなることです。

他の興味深い観察のカップル

1)出力ファイルに何かをキャットすると、プログラムは問題なく更新を続けることができます

2)自分のプログラムの複数のインスタンスが同じファイルに書き込んでいる場合、すべてが再び正常になります

複数の書き込みを防ぐために必須のロックがあることは理解していますが、その下で何が起こっているのかを理解しようとしています。また、この種のシナリオは、一部のロガー(システムログ、Apacheログなど)では正常に動作します。

この振る舞いを説明するためのアイデアはありますか?また、これをさらにデバッグする方法についてのヒントはありますか?

私のコードはとてもシンプルです:

  1 int main(int argc, char** argv)
  2 {
  3     const char* buf;
  4     if(argc < 2)
  5         buf = "test->";
  6     else
  7         buf = argv[1];
  8 
  9     int fd; 
 10     if((fd = open("test.log", O_CREAT|O_WRONLY|O_APPEND, 0644)) == -1) {
 11         perror("Cannot open test.log");
 12         exit(1);
 13     }   
 14 
 15     int num_bytes = strlen(buf), num_bytes_written = -1; 
 16 
 17     while(1) {
 18         if((num_bytes_written = write(fd, buf, num_bytes)) == -1) {
 19             perror("Could not write to fd");
 20         }   
 21         fsync(fd);
 22         sleep(5);
 23     }   
 24 }   
4

2 に答える 2

1

vim(1)エディターが終了すると、元のファイルが編集されたバージョンに置き換えられている可能性があります。プロセスは元のファイルを開いたままにしていますが、ディレクトリエントリが置き換えられたという意味でそのファイルは存在しないため、ファイルをまだ開いていないプロセスはそのファイルにアクセスできません。これで、他のプロセスからアクセスできないファイルにプロセスが追加されます。プロセスがファイルを閉じると、ファイルは完全に失われます(パーティション回復プログラムを実行しない限り)。

于 2010-10-17T16:19:28.747 に答える
0

vimエディターは、キャッシュされたバージョンのファイルで動作します。他のプログラムが元のファイルに追加する間、このキャッシュを変更します。vimで保存すると、元のファイルが更新されたキャッシュファイルで上書きされ、すべてのログが失われます。

于 2010-10-17T08:12:02.990 に答える