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. Varnish 初识

    基础 Varnish Cache是​​一种Web应用程序加速器,也称为缓存HTTP反向代理.您将它安装在任何HTTP的服务器前面,并将其配置为缓存内容.Varnish Cache非常非常快.它通常可以 ...

  2. 物理层PHY 和 网络层MAC

    PHY模块简介 物理层位于OSI最底层,物理层协议定义电气信号.线的状态.时钟要求.数据编码和数据传输用的连接器. 物理层的器件称为PHY. 上图里的灰色方框图里的就是PHY芯片内部模块图. MAC器 ...

  3. 骨灰级玩家体验带你测试体验天使纪元OL折扣端

    刘亦菲代言吸引了我才进入游戏的(不知道有多少人和我一样)这个游戏没有一些骨灰级玩家带,真的很费时间费钱.   天使纪元5折折扣端(点击下载),其实是一个良心老平台,苹果,安卓.H5都支持的平台,采用最 ...

  4. shell脚本中如何插入其它脚本?

    答: 示例如下: #!/bin/sh . added.sh #include other script echo "hello"

  5. P4114 Qtree1

    思路 树剖一发,注意对LCA的处理 代码 #include <cstdio> #include <algorithm> #include <cstring> usi ...

  6. IDLE清屏扩展

    新建ClearWindows.py,复制以下代码: class ClearWindow: menudefs = [ ('options', [None, ('Clear Shell Window', ...

  7. vmstat命令参数介绍

    vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...

  8. Rancher2.0与DataDog集成部署

    目录 一.简要介绍 二.注意事项 三.部署过程 四.运行截图 五.参考链接 一.简要介绍: 看了Rancher中文官网上的一篇关于DataDog部署的文章,自己尝试了一下,没有成功,主要是自己对Dat ...

  9. ZT: C#不建类直接Json解析与取值

    C#不建类直接Json解析与取值 2017年10月19日 15:58:22 圆圆娃哈哈 阅读数:701    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn. ...

  10. 学习笔记70—Photoshop画齿轮

    具体步骤如下: 1)选择多边形工具: 2)设置齿轮个数及颜色相应参数: 3)画出模型: 4)找到上图模型的中心 (借助:ctrl + T),选择椭圆工具,并 长按Shift+Alt, 画出圆: 5) ...