【问题标题】:atomic append on a file descriptor, but at what offset?文件描述符上的原子附加,但偏移量是多少?
【发布时间】:2010-11-17 17:09:35
【问题描述】:

在 unistd.h 中

使用带有 O_APPEND 标志的 open() 可以将原子写入始终写入文件末尾...

这很好,但是如果我需要知道它以原子方式附加到文件的偏移量怎么办...?

我意识到 O_APPEND 通常用于日志文件,但我实际上想知道它在文件中以原子方式附加的偏移量。

我没有看到任何明显的方法来做到这一点..?有人知道吗?

谢谢

【问题讨论】:

  • 追加操作不是原子的,除非你写入无缓冲的数据,一次一个扇区。
  • 如果设置了文件状态标志的 O_APPEND 标志,则文件偏移量应在每次写入之前设置为文件末尾,并且在更改文件偏移量和更改文件偏移量之间不会发生中间文件修改操作写操作。 opengroup.org/onlinepubs/009695399/functions/pwrite.html

标签: c++ c linux posix unistd.h


【解决方案1】:

要获取文件描述符中的当前位置,请使用 lseek() 和偏移量 0SEEK_CUR

int fd = open(...);
if (fd) {
    off_t positionWhereAppendingBegins = lseek(fd, 0, SEEK_CUR);
    write(...);
    close(fd);
}

请注意,如果描述符是通过其他方式打开的,即通过socket(),这不会为您提供可靠的结果。

【讨论】:

  • 但这是不准确的,因为在写入调用中,偏移量会自动更新到文件末尾。
  • 不会回去修改positionWhereAppendingBegins。在超出范围之前,该值保持不变。
  • 关键是lseek()write()之间的另一个进程干预write()将意味着写入发生在与lseek()返回的偏移不同的偏移处。
  • 在我的示例中,文件描述符刚刚被打开。没有其他人知道它。在一个格式良好的程序中,没有其他人有机会使用它调用write()
【解决方案2】:

文件被写入文件打开时进程获得的文件偏移量。如果另一个进程在打开和写入之间写入文件,则文件的内容是不确定的。

处理多个进程写入单个文件的正确方法是让所有进程打开带有 O_APPEND 标志的文件,获得排他锁,一旦获得锁,在写入文件之前寻找文件末尾文件,最后关闭文件释放锁。

如果要在两次写入之间保持文件打开,请通过打开带有 O_APPEND 标志的文件来启动该过程。本例中的写循环是获取排他锁,寻找文件末尾,写入文件,释放锁。

如果确实需要文件位置,lseek会返回调用者文件描述符在调用时的文件偏移量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2013-11-08
    • 2017-09-05
    • 1970-01-01
    相关资源
    最近更新 更多