gpt4 book ai didi

linux - O_SYNC 写入何时在页面缓存(mmap 文件)中可见?

转载 作者:太空狗 更新时间:2023-10-29 11:16:11 27 4
gpt4 key购买 nike

我有一个 mmap 只读/共享文件,多个线程/进程同时读取数据。允许单个写入器随时修改数据(在单独的共享内存区域中使用互斥锁)。使用底层文件上的 write() 执行更改。整体设置是旨在实现事务一致性的数据库的一部分。

会以任意顺序写出任意数量的数据页,然后调用fdatasync()。在写入根页面之前,文件中没有任何内容指向这些更改过的页面。根页面使用使用 O_SYNC 打开的第二个文件描述符写入,因此在成功写入根页面之前写入不会返回。所有正在写入的页面都是 mmap 区域的一部分,因此它们最终将对所有读者可见。

问题是——一旦内核将用户缓冲区复制到页面缓存中,最终的 O_SYNC 写入是否立即变得可见?还是仅在同步写入完成后才可见?我已经通读了一些内核代码,但并没有完全遵循它;在我看来,用户数据被立即复制到页面缓存,然后安排写入,然后等待写入完成。同时,写入的数据已经存在于页面缓存中,因此读取进程可以立即看到。这是不可取的,因为如果物理写入实际上失败了,则必须回滚事务,并且决不允许读者看到由不成功的事务写入的任何内容。

有人确切知道 O_SYNC 写入如何与页面缓存交互吗?我想为了安全起见,我可以使用互斥锁来包装对根页面的访问,但这会增加一层开销,最好避免。

最佳答案

在正式的 POSIX 标准下,更新到 MAP_SHARED区域可以随时出现。同步 I/O 定义指定写入仅在数据到达物理介质后返回,但不讨论其他进程看到的数据。

在 Linux 上的实践中,它按照您所描述的那样工作 - 页面缓存是调度设备写入的暂存区域,并且 MAP_SHARED映射是页面缓存的 View 。

作为替代方案,您可以将根页面的副本放入共享的匿名区域。读取进程将使用该副本,而写入进程将在将根页面同步到磁盘后更新它。不过,您仍然需要同步,因为您无法自动更新整个页面。

关于linux - O_SYNC 写入何时在页面缓存(mmap 文件)中可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7061910/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com