这一篇blog想谈一谈关于fsync函数。fsync的全称是file Synchronize(我猜的)。

为什么要讨论fsync函数呢,因为程序在进行大数据存储的时候,比如说16GB,这个时候,使用fsync会大大的增加程序运行的时间,尤其是对于实时采集自然界的电磁信号的科研人员来说,可能会错过很关键的信号。但是因为我们要保证数据的安全性,所以需要实时的使用fsync将在kernel page cache中的数据落盘,这样就算断电,或者发生意外的情况,我们的数据都不会丢失。所以说fsync是一把双刃剑。

首先简单的介绍一下linux下fwrite写数据的底层步骤:

第一步:fwrite将数据写入c标准的I/O缓冲区中,这个缓冲区可以用setbuf来设置大小,如果设置了大小的话,当缓冲区满了的时候,就会刷新一遍,往kernel page cache中写入,如果不设置buffer大小的话,那就等程序执行fflush,将数据写入kernel page cache。

第二步:fwrite之后的第二步就是fflush,当程序执行完fflush之后,这个时候写入的数据仍然在内存中,如果发生断电,数据是不予保留的,只有真正写入硬盘中,才有保证。

第三步:fsync,将数据从kernel page cache写入物理设备中。

第四步:fclose。

如果说你没有fsync,但是你程序跑完了,也fclose了,你的数据肯定是保存好了的,但是你怎么能保证在程序运行的时候,不发生任何意外情况呢,程序员考虑的应该是尽可能的完整。但是fsync会大大影响效率。但是不是没有办法解决这个问题,需要一定的前提,如果你的程序总是在创建一个新文件,然后写入,而不是去修改一个已经存在的文件,你想提高效率的话,可以删除fsync,因为被修改的文件内容总是保存在kernel page cache中。

当程序退出时,内存中的数据会被自动写入磁盘文件,因此通常情况下是不必调用fsync函数的。 但是,如果你的程序在写入数据之后立即退出,那么内存中的数据可能不会被写入磁盘文件,这时就必须调用fsync函数来强制写入磁盘文件。

如果你确实希望写入数据时尽快地返回,那么你可以选择不调用fsync函数。 但是,这意味着数据可能不会立即写入磁盘文件,这可能会导致数据丢失。 因此,在这种情况下,你需要权衡速度和安全之间的关系。