【问题标题】:Concurrent writing and reading of a file文件的并发读写
【发布时间】:2021-07-26 01:00:41
【问题描述】:

我需要在写入文件时对其进行备份。正在运行的程序会定期将数据附加到文件中,而另一个应用程序会将内容复制到备份文件中。

我的方法:备份程序每x 秒唤醒一次,并从原始文件中的前一个偏移量发出pread 请求y 字节。如果 pread 调用返回一个正整数,表示检索到的字节数,我将它们写入备份文件。

这种方法会导致备份文件不一致吗? pread 调用是否有可能读取未完全写入原始文件的数据块?请注意,数据仅附加到原始文件中。初步测试表明这种方法效果很好,但它可能是偶然的。

编写器代码:

fd = open_file();
while(!done) {
    do_some_work();
    write(fd, buf, bufsize);
}

阅读器代码:

fd_in  = open_original_file();
fd_out = open_backup_file();

while(!done) {
    // Issue a read call
    bytes_in = pread(fd_in, buf, chunksize, current_offset);

    // Data retrieved
    if(bytes_in > 0) {
        pwrite(fd_out, buf, bytes_in, current_offset);
        current_offset += bytes_in;
    }
    sleep(5);
}

【问题讨论】:

  • 关于:fd = open_file(); while(!done) { do_some_work(); write(fd, buf, bufsize); } 这永远不会设置 done 变量。
  • write() 的调用将数据放入输出流缓冲区。只有当缓冲区溢出时,数据才会真正写入文件。建议在每次调用write() 后使用fflush(),以便将数据立即传递到文件中。

标签: c linux file-io io posix


【解决方案1】:

是的,它应该是安全的。 POSIX I/O 保证顺序一致性;也就是说,对同一文件的并发访问将完成,就好像它们以某种顺序执行一样。写入是原子的;读取只能读取完全写入的数据。

一些网络文件系统削弱了顺序一致性要求,但我怀疑它们会违反写入的原子性。

【讨论】:

  • 来自stackoverflow.com/questions/35595685/…,“POSIX 不提供任何最低限度的读写原子操作保证,除了管道上的写入(保证写入最多 PIPE_BUF (≥ 512) 字节)是原子的,但读取没有原子性保证)"
  • 我的文件系统是 xfs,因为这似乎会影响写入和读取的原子性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多