Не удается добавить в файл, когда какой-то другой процесс пишет в него в * nix системах - PullRequest
0 голосов
/ 17 октября 2010

У меня есть очень простой кусок кода, который просто записывает небольшое количество данных в файл через некоторый регулярный интервал. Как только моя программа создала файл и добавила некоторые данные, когда я открываю этот файл в vim (или любом другом редакторе в этом отношении) и редактирую его, мой процесс больше не может обновлять файл. Я не вижу никаких ошибок, возвращаемых из системного вызова. Я попытался отследить системные вызовы и не заметил ничего странного, даже когда файл НЕ обновлялся.

Поскольку каждый процесс получает свою собственную запись в таблице файлов с текущим смещением, все, что я ожидал, это выходной файл с данными, перемежаемыми с записями из двух не взаимодействующих процессов (возможно, искаженных тоже). Но я наблюдаю за тем, что моя программа больше не может обновлять файл, как только в него записывает другой редактор.

Пара других интересных наблюдений

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 }   

Ответы [ 2 ]

1 голос
/ 17 октября 2010

При выходе из редактора vim (1), скорее всего, заменит исходный файл отредактированной версией. Ваш процесс удерживает исходный файл открытым, но этот файл больше не существует в том смысле, что его запись в каталоге была заменена, и поэтому ни один процесс, у которого еще нет открытого файла, не может получить к нему доступ. Ваш процесс теперь добавляет файл, к которому нет доступа ни у одного другого процесса. Как только ваш процесс закроет файл, он исчезнет навсегда (если вы не запустите программу восстановления разделов).

0 голосов
/ 17 октября 2010

Ваш редактор vim работает с кэшированной версией вашего файла. Он изменяет этот кеш, в то время как другие ваши программы добавляют к исходному файлу. Когда вы сохраняете с помощью vim, вы перезаписываете оригинальный файл обновленным кэшированным файлом и теряете все журналы.

...