当某些其他进程在* nix系统上写入时,无法附加到文件

时间:2010-10-17 07:41:52

标签: file-io unix concurrentmodification

我有一段非常简单的代码,它只是以一定的间隔将少量数据写入文件。一旦我的程序创建了文件并附加了一些数据,当我在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 个答案:

答案 0 :(得分:1)

当vim(1)编辑器退出时,很可能用编辑后的版本替换原始文件。您的进程保持原始文件处于打开状态,但该文件已不再存在,因为它的目录条目已被替换,因此,没有已打开文件的进程可以访问它。您的进程现在附加到任何其他进程无法访问的文件。一旦你的进程关闭了文件,它将会永远消失(除非你运行分区恢复程序)。

答案 1 :(得分:0)

您的vim编辑器适用于您文件的缓存版本。当您的其他程序附加到原始文件时,它会修改此缓存。使用vim进行保存时,使用更新的缓存文件覆盖原始文件并松开所有日志。