使用fsync()确保实时系统的数据一致性

时间:2017-08-31 22:31:29

标签: c++ real-time fsync

我很难确定将fsync()实现到实时系统的最佳方法。我需要满足的唯一要求是fsync()不得破坏帧(100 Hz - 每帧10 ms)。我做了一些初始基准测试,我目前倾向于在每次固定大小写入(大约1 KB)之后调用fsync(),直到文件完成。我给出的另一个建议是在较慢的任务/线程上调用fsync()(在整个文件的末尾,或者这个较慢任务的每一帧)。

你可能会因为我描述的问题以及我探索的选项而猜测我是新手,但无论如何都要用复杂的东西打我。我可以尝试其他任何实现吗?什么是最有效/最好的方法呢?

谢谢!

编辑:我正在运行的操作系统是Linux。要执行写入,我使用带有FILE *的C库来执行文件I / O.由于目前这是在一个100赫兹的任务上发生的,那就是每秒100帧,每帧写1 KB(这只是针对这个特定的操作而不考虑其他操作员在此帧中其他地方发生的其他写入)。

1 个答案:

答案 0 :(得分:2)

你真的需要详细说明你正在使用什么操作系统来获得一个好的答案。大多数类Unix操作系统没有实时保证的概念,而且通常会对文件I / O有很大的保证。

对于本答的其余部分,我将假设您使用的是现代Linux的一些变体,它确实具有一些有限的实时调度功能。我还假设您正在将数据写入标准文件系统(ext [234],btrfs等)上的简单文件中。我还假设您正在使用低级read()/ write()样式系统调用,而不是使用C-stdio或C ++ iostreams进行应用程序级缓冲......

Linux的文件系统层的设计方式,所有进出磁盘的I / O最终都缓存在内存中,并根据需要异步编组到硬件存储。有一个内核线程会在可配置的时间间隔内定期将内存中的脏页刷新到磁盘,并且该时间间隔是可调的,可以使用sysctl/proc/sys接口进行更改。在轻量级I / O负载下,这种异步方案足以确保您的进程不会在I / O上长时间阻塞,但是当您的I / O负载开始超过可以物理写入的数量时磁盘,您的应用程序将阻止,这可能是一个非常冗长的操作。

您正在对fsync()调用执行的操作是绕过内核的异步机制来分摊I / O开销,确保在I / O操作完成之前刷新您创建的脏页。如果你使用太小的I / O设置大小来实现这一点,实际上,你反而直觉地使I / O更慢。

假设您对典型I / O大小的估计是每帧1KiB,假设每秒约30-60帧是正确的,我相信这将在每秒30-60KiB之间,这应该在操作系统自己将数据刷新到磁盘的能力。因此,我对你的建议就是把罐头放在路上,并担心如果它成为问题就阻塞I / O.但是,我还会花一些时间编写一些代码来衡量写入系统调用所花费的时间并测量它以确保:)