【问题标题】:fopen multiple times in append modefopen 在追加模式下多次
【发布时间】:2021-11-12 13:56:42
【问题描述】:

我有多个线程试图登录到同一个文件。

每个线程都有一个指向文件的FILE *FILE *s 以附加 ('a') 模式打开并使用行缓冲。

在同一个进程中打开多个FILE *到同一个文件是根据ANSI C定义的实现。

有没有人知道 MacOS、FreeBSD 和 Linux 的具体实现行为,特别是每个 FILE * 是否有自己的行缓冲区,以及是否有丢失或交错写入的机会。

【问题讨论】:

  • OT:拥有一个处理写入日志文件的函数(使用正确的互斥锁)会简单得多。像这样从多个线程写入同一个文件的竞争条件迟早会​​导致问题
  • @UnholySheep 在一般情况下不正确。 Posix 保证原子写入文件。

标签: c file posix fopen


【解决方案1】:

MacOS、FreeBSD 和 Linux 都是 POSIX 系统。因此,每个FILE* 都有自己的用户空间缓冲区(如果禁用它,则没有),一旦该缓冲区被刷新,它将被写入底层文件描述符。 POSIX 保证追加打开的文件描述符写入是原子的,因此不会丢失任何数据。只要您的数据没有被拆分为多个刷新,它也不会相互交错。

【讨论】:

  • 虽然答案是正确的,但它肯定会受益于支持文档的引用。
  • 行缓冲写入发生在换行符或缓冲区已满时,因此大于缓冲区大小的写入可能会被拆分。
  • POSIX 保证追加打开的文件描述符写入是原子的,因此不会丢失任何数据。 但它不保证对 fwrite()/fprintf() 的调用之间有任何对应关系/等等。在FILE * 结构上以及对基础文件描述符上的write() 的任何调用。 只要您的数据没有被拆分为多个刷新,它也不会相互交错。 但是没有保证方法可以控制它。您不能禁用缓冲 - 如果在 fprintf() 和底层写入等调用之间没有保证映射,一个 fwrite() 可能会导致多个 write() 调用。
  • 如果你真的想保证非交错数据,你必须将你想要写入的整个包编组为一个块并调用write()。当然,Linux 然后转身并打破 POSIX 保证,如果您的写入跨越页面边界,则不会撕裂写入。关于代码维护者更喜欢撕毁写入以便他可以中断它的一些事情,以及对 POSIX 合规性的如此多的东西......请参阅stackoverflow.com/questions/10650861/… 了解一些背景
猜你喜欢
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 2016-12-25
  • 2012-02-16
  • 2018-02-11
  • 2011-11-20
  • 2021-10-20
  • 1970-01-01
相关资源
最近更新 更多