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. 目标URL存在跨站漏洞和目标URL存在http host头攻击漏洞处理方案

    若需要学习技术文档共享(请关注群公告的内容)/讨论问题 请入QQ群:668345923 :若无法入群,请在您浏览文章下方留言,至于答复,这个看情况了 目录 HTTP协议详解 引言 一.HTTP协议详解 ...

  2. js时间相关

    let date = new Date(); date.getYear(); //获取当前年份(2位) date.getFullYear(); //获取完整的年份(4位) date.getMonth( ...

  3. Tomcat笔记 #01# WEB应用管理工具简介

    索引 查看JVM以及SERVLET/接口的情况 动态管理WEB应用 Tomcat自带了一个基于网页的web应用管理工具,可以帮助我们监控&管理部署上去的WEB APP,特别方便!恰好之前碰到的 ...

  4. flutter- 圆角

    单个圆角变化 Container( height: 200, decoration: BoxDecoration( color: Colors.green, borderRadius: BorderR ...

  5. varnish 测试

    安装 通过epel 源 yum 安装 [root@localhost varnish]# rpm -ql varnish /etc/logrotate.d/varnish /etc/varnish / ...

  6. mysql5.7.21下载及安装步骤

    以前都是用的5.6的数据库,现在想着换个新版本数据库.跟上时代的步伐,于是安装了一天才安装好.具体步骤如下: 1.官网下载mysql解压zip版,由于客户端安装版都是32位的,我的电脑是64位系统,所 ...

  7. linux下的缓存机制及清理buffer/cache/swap的方法梳理 (转)

    一.缓存机制介绍 在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果 ...

  8. Maven的基本概念

    一.Maven的基本概念' Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理. 1.1 ...

  9. Python下关于RSA解密模块的使用

    最近筹备一场CTF比赛发现了一道关于RSA解密的题如下: #小明得到了一个 RSA 加密信息,你能帮他解开吗? n = 4106906565495961459775020773869808579876 ...

  10. scala链接mysql

    方法一:链接并操作mysql //链接Mysqlval driver = "com.mysql.jdbc.Driver"val url = "jdbc:mysql://1 ...