调用fwrite()后是否必须使用fflush()?
fwrite 后必须调用 fflush 的场景说明
C 标准库的文件 I/O 默认自带用户态缓冲区,fwrite 写入的内容会先暂存在这个用户态缓冲区中,并不会直接同步到内核。你测试时没有触发异常,是刚好命中了缓冲区自动刷新的条件(比如写入数据量达到缓冲区阈值、写完后立刻调用了 fclose 或者进程退出),但以下场景必须手动调用 fflush 才能保证其他进程读取到最新内容:
- 写入数据量小于缓冲区阈值的场景:磁盘文件默认使用全缓冲模式,缓冲区大小通常为 4KB/8KB(取决于系统实现),如果单次写入的内容远小于缓冲区大小,内容会一直滞留在用户态缓冲区,直到缓冲区满才会自动刷入内核。这种场景下其他进程读取文件时完全看不到新写入的内容,必须主动调用
fflush触发数据同步。 - 强一致并发读写场景:如果业务要求写入操作完成后立刻对所有读进程可见,就不能依赖不可控的自动刷新逻辑,必须每次写完就调用
fflush,否则高并发场景下极容易出现读进程拿到过期数据的问题。 - 长期运行的常驻进程写文件场景:比如后台日志服务、常驻守护进程等,会长期持有同一个文件句柄不关闭,也不会主动退出,如果每次写入的内容量很小,缓冲区可能数小时都不会被填满,新写入的内容会一直留在用户态,外部读取文件时看不到任何更新,必须手动调用
fflush定时或者每次写入后同步。
额外注意:
fflush仅负责把数据从用户态缓冲区同步到内核页缓存,此时数据还没有落到物理磁盘,如果需要保证数据断电不丢失,在调用fflush之后还需要通过fileno()拿到文件描述符,再调用fsync/fdatasync做持久化。如果只需要保证其他进程可以读到最新内容,单独调用fflush就足够。
内容的提问来源于stack exchange,提问作者Arre
相关产品推荐
相关产品推荐

