int fflush(FILE *stream);
If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
如果 stream 指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么 fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。否则,它的行为是未定义的。
(宿主环境可以理解为操作系统或内核).

所以如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用fflush(stdin)是不正确的。

The  function  fflush  forces a write of all user-space buffered data for the given output or update stream via  the stream underlying write function.  The open status of the stream is unaffected. If the stream argument is NULL, fflush flushes all open output streams.
Note  that  fflush() only flushes the user space buffers provided by the C library.  To ensure that the data is physically stored on disk the kernel buffers must be flushed too, e.g. with sync(2) or fsync(2).

int fsync(int fd);
fsync copies all in-core parts of a file to disk, and waits until the device reports that all parts are on stable storage.  It also updates metadata stat information. It does not necessarily ensure that the entry  in  the directory  containing the file has also reached disk.  For that an explicit fsync on the file descriptor of the directory is also needed.

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent storage device) where that file resides. The call blocks until the device reports that the transfer has completed. It also flushes metadata information associated with the file (see stat(2)).

1.提供者fflush是libc.a中提供的方法,fsync是系统提供的系统调用。
2.原形fflush接受一个参数FILE *.fflush(FILE *);fsync接受的时一个Int型的文件描述符。fsync(int fd);
3.功能fflush:是把C库中的缓冲调用write函数写到磁盘[其实是写到内核的缓冲区]。fsync:是把内核缓冲刷到磁盘上。 
4.fsync 将文件相关的所有更改都发送到disk device。 这个调用是阻塞的,直到disk通知此函数传输完成。此函数也会将该文件的文件信息flush到disk。
5.fsync最终将缓冲的数据更新到文件里。

所以可以看出fflush和fsync的调用顺序应该是:
C标准库的I/O缓冲区-----fflush---------〉内核缓冲区--------fsync-----〉磁盘缓冲区
 
Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.

fdatasync() is similar to fsync(), but does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled. For example, changes to st_atime or st_mtime (respectively, time of last access and time of last modification; see stat(2)) do not not require flushing because they are not necessary for a subsequent data read to be handled correctly. On the other hand, a change to the file size (st_size, as made by say ftruncate(2)), would require a metadata flush.

The aim of fdatasync(2) is to reduce disk activity for applications that do not require all metadata to be synchronised with the disk.

fdatasync与fsync的区别在于fdatasync不会flush文件的metadata信息。这个是为了减少对磁盘的操作

Notes
If the underlying hard disk has write caching enabled , then the data may not really be on permanent storage when fsync() / fdatasync() return.

C标准库的I/O缓冲区有三种类型:全缓冲、行缓冲和无缓冲。当用户程序调用库函数做写操作时, 不同类型的缓冲区具有不同特性。

全缓冲

如果缓冲区写满了就写回内核。常规文件通常是全缓冲的。

行缓冲

如果用户程序写的数据中有换行符就把这一行写回内核,或者如果缓冲区写满了就写回内 核。标准输入和标准输出对应终端设备时通常是行缓冲的。

无缓冲

用户程序每次调库函数做写操作都要通过系统调用写回内核。标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备。

除了写满缓冲区、写入换行符之外,行缓冲还有两种情况会自动做Flush操作。如果: 
用户程序调用库函数从无缓冲的文件中读取 
或者从行缓冲的文件中读取,并且这次读操作会引发系统调用从内核读取数据

如果用户程序不想完全依赖于自动的Flush操作,可以调fflush函数手动做Flush操作。 
#include <stdio.h> 
int fflush(FILE *stream); 
返回值:成功返回0,出错返回EOF并设置errno
fflush函数用于确保数据写回了内核,以免进程异常终止时丢失数据,如fflush(stdout); 作为一个特例,调 用fflush(NULL)可以对所有打开文件的I/O缓冲区做Flush操作。

参考:https://www.cnblogs.com/alantu2018/p/8472718.html

fflush 和 fsync 的区别的更多相关文章

  1. read/write/fsync与fread/fwrite/fflush的关系和区别

    read/write/fsync: 1. linux底层操作: 2. 内核调用, 涉及到进程上下文的切换,即用户态到核心态的转换,这是个比较消耗性能的操作. fread/fwrite/fflush: ...

  2. 同步内核缓冲区sync、fsync和fdatasync函数

    转自http://www.2cto.com/os/201409/339460.html 同步内核缓冲区 1.缓冲区简介 人生三大错觉之一:在调用函数write()时,我们认为该函数一旦返回,数据便已经 ...

  3. 同步内核缓冲区 sync、fsync和fdatasync函数

    同步内核缓冲区 1.缓冲区简单介绍 人生三大错觉之中的一个:在调用函数write()时,我们觉得该函数一旦返回,数据便已经写到了文件里.可是这样的概念仅仅是宏观上的.实际上.操作系统实现某些文件I/O ...

  4. O_DIRECT与O_SYNC区别(转)

    O_DIRECT和O_SYNC是系统调用open的flag参数.通过指定open的flag参数,以特定的文件描述符打开某一文件. 这两个flag会对写盘的性能有很大的影响,因此对这两个flag做一些详 ...

  5. sync/fsync/fdatasync的简单比较

    此文主要转载自 http://blog.csdn.net/zbszhangbosen/article/details/7956558 官网上有关于MySQL的flush method的设置参数说明,但 ...

  6. C/C++ 笔试题

    /////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...

  7. C/C++笔试题(很多)

    微软亚洲技术中心的面试题!!! .进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2 ...

  8. Linux系统:保证数据安全落盘

    在很多IO场景中,我们经常需要确保数据已经安全的写到磁盘上,以便在系统宕机重启之后还能读到这些数据.但是我们都知道,linux系统的IO路径还是很复杂的,分为很多层,每一层都可能会有buffer来加速 ...

  9. Java I/O体系从原理到应用(非原创)

    基础概念 在介绍I/O原理之前,先重温几个基础概念: 1 操作系统与内核 操作系统:管理计算机硬件与软件资源的系统软件内核:操作系统的核心软件,负责管理系统的进程.内存.设备驱动程序.文件和网络系统等 ...

随机推荐

  1. SNMP理解

    前两天项目要求一个附加功能,远程监视服务器的运行状况,要定期监视指定端口,指定业务,还包括服务器的磁盘空间,内存,CPU使用率等等.这头俩事还好说,ping和telnet也就搞定了,实在不行就开个so ...

  2. Centos7配置SVN服务端

    环境 Centos 7 SVN 1.7 安装SVN Shell> yum install subversion -y 准备配置和仓库 Shell> mkdir -p /mydata/rep ...

  3. 关于springMVC的细节

    1. Controller的生命周期 Spring框架默认创建的对象是单例.所以业务控制器是一个单例对象. 单例对象带来的问题,就是请求的数据如果放在成员变量上面,会相互影响. 请求使用同一个对象处理 ...

  4. Spring 极速集成注解 redis 实践

    Redis 做为基于内存的 Key-Value 数据库,用来做缓存服务器性价比相当高. 官方推出的面向 Java 的 Client Jedis,提供了很多接口和方法,可以让 Java 操作使用 Red ...

  5. Bytom储蓄分红合约解析

    储蓄分红合约简介 储蓄分红合约指的是项目方发起了一个锁仓计划(即储蓄合约和取现合约),用户可以在准备期自由选择锁仓金额参与该计划,等到锁仓到期之后还可以自动获取锁仓的利润.用户可以在准备期内(dueB ...

  6. c# mongodb drive IngoreExtraElements and RegisterClassMap

    private static void RegisterClassMaps(IEnumerable<Type> clrTypes) { foreach (var clrType in cl ...

  7. Pandorabox(Openwrt) 双宽带(WAN) 叠加网络实战

    准备 一台已经刷好Pandorabox(Openwrt)的路由器.两条宽带 实战环境 固件:PandoraBox R8.1.12 By Lean 硬件:K2P A1版 过程 配置VLAN 为了将一个L ...

  8. 一、Java JUC简介

    在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池.异步 IO 和轻 ...

  9. zookeeper调试命令

    转载自 https://www.cnblogs.com/andy6/p/7674028.html 一.zkServer.sh 1.查看 zkServer.sh 帮助信息[root@bigdata05 ...

  10. 《Clean Code》阅读笔记

    Chapter 2  命名 命名要表现意图 避免歧义和误导,增强区分 命名可读性:便于发音,增强印象,便于交流 命名可查性:增强区分,便于搜索 类和对象的命名:名词或名词短语 方法的命名:动词或动词短 ...