linux 下文件同步函数(fflush、sync、fsync、fdatasync)之间差异

遇到机器异常关机时,写log文件信息丢失问题,所以记录下。
  Linux实现中在内核设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲区进行。当我们向文件写数据时,内核通常先将数据复制到一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待写满或者内核需要重用该缓冲区以便存放其他数据时,才会将该缓冲区排入输出队列,然后等它到达队首时,才进行实际的I/O操作。这就是被称为 延迟写的输出方式。
  延迟写减少了磁盘读次数,但是却减低了文件内容跟新的速度。当系统发生故障时,延迟写的方式可能造成文件跟新丢失。为了应对此种情况,linux下提供了sysnc,fsync,fdatasync三个函数来保证实际文件系统与缓冲区中内容的一致。

#include<unistd.h>

int fsync(int fd);
int fdatasync(int fd);
void sync(void);

《1》、sync
    该函数只是将所有修改过的块缓冲区排入写队列,然后就返回,他并不等待实际写磁盘操作结束
《2》、fsync
    只对由文件描述符fd指定的一个文件起作用,并且等待写磁盘操作结束才返回。
《3》、fdatasync
    类似于fsync,但是它只影响文件的数据部分。而除数据外,fsync还会同步更新文件的属性。
《4》C库的fflush
    标准的I/O函数(如fread,fwrite)会在内存建立缓冲,该函数刷新内存缓冲,将内容写入内核缓冲,要想将其写入磁盘,还需要调用fsync(先调用fflsuh然后再调用fsync,否则不起作用);

关系:

      c库缓冲-----fflush---------〉内核缓冲--------fsync-----〉磁盘

1、例子

int main()
{
    FILE* wstream = fopen("test.log","wb+");
    int wfd = -1;
    if(wstream)
    {
        char tmp_str[12]="test file sync";
        fwrite(tmp, 1, strlen(tmp_str), wstream);

        fflush(wstream);  //写到缓冲区

        wfd = fileno(wstream);  //由文件流获取文件描述符
        if(wfd != -1)
        {
            fsync(wfd);  //由缓冲区写到磁盘
        }

        fclose(wstream);
    }
    else
    {
        perror("Open test.log: ");
    }

    return 0;
}

2、参考:
《1》、https://blog.csdn.net/xiaoshengqdlg/article/details/44114939
《2》、unix环境高级编程第三版 – 3.13

猜你喜欢

转载自blog.csdn.net/FPGATOM/article/details/84703491