FILE系列函数:
fopen,fclose,fflush,setbuf,fwrite,fread
通过fopen打开的文件,默认在用户空间会开一个buf,一般是4K或8K, fwrite的数据会写到这块用户空间的buf中, 此时数据对外不可见,因为还在进程的buf空间中; 满了之后调用fd的write函数写入系统buffer, 此时数据对外部用户已经可见,但实际上还没有到物理硬盘中.
如果想禁用FILE的用户空间buf,可以通过setbuf进行设置.
fflush只是把用户空间的buf flush到系统buffer中,并没有到物理硬盘,所以还是会导致数据丢失(断电情况下).
数据一旦到系统buffer中, 进程crash数据是不会丢失的,只有down机才会导致数据丢失.
FD系列函数:
open,close,fsync,fdatasync,write,read
open有很多种模式, 关系到cache问题的有O_DIRECT和O_SYNC两个. O_DIRECT是指禁用该fd的系统cache,所有的读取和写入都直接到硬盘IO,因为用户空间自己做了读写cache. O_SYNC会保证每个write的数据持久到硬盘后再返回.
默认情况下open的fd, write会保证数据写入到系统buffer中,不保证到硬盘; 例外情况参见open的O_DIRECT和O_SYNC模式.
fsync和fdatasync会保证数据持久化到硬盘.
有些硬盘可能会有自己的通过电池驱动的写cache,这时候fsync也不能保证数据持久化到硬盘;但由于有电池驱动,即使断电也不会丢失数据.
MMap系列函数:
mmap, munmap, msync
mmap后,对空间的每次读写都是直接进入到系统page cache中,外部程序可见。但是同FD系列函数一样,page cache中如果要持久化到硬盘,需要调用msync。
参看man时,需要特别注意NOTES章节