首页 > Linux文件同步写的阻塞时间疑惑

Linux文件同步写的阻塞时间疑惑

这里有两份代码,都是读1.dat的内容同步写到2.dat。
1.dat的内容是1亿个1,大小95.37MB。
另:延迟写的速度大概是2s

1.利用fcntl函数

#include "apue.h"
#include <fcntl.h>
#define BUFFSIZE 4096

void set_fl(int fd, int flags);

int main()
{
    int     n;
    char    buf[BUFFSIZE];
    set_fl(STDOUT_FILENO, O_SYNC);
    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");

    if (n < 0)
        err_sys("read error");
    exit(0);
}

void set_fl(int fd, int flags)
{
    int val;

    if (val = fcntl(fd, F_GETFL, 0) < 0)
        err_sys("fcntl F_GETFL error");

    val |= flags;

    if (fcntl(fd, F_SETFL, val) < 0)
        err_sys("fcntl F_SETFL error");
}

./a.out < 1.dat >2.dat
real    0m3.080s
user    0m0.002s
sys     0m0.174s

2.使用O_SYNC打开文件2.dat

#include "apue.h"
#include <fcntl.h>
#define BUFFSIZE 4096


int main()
{
    int     n;
    char    buf[BUFFSIZE];
    int fd = open("2.dat",O_WRONLY|O_SYNC);
    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (write(fd, buf, n) != n)
            err_sys("write error");

    if (n < 0)
        err_sys("read error");
    exit(0);
}

./a.out < 1.dat
real    0m50.386s
user    0m0.010s
sys     0m0.706s

如果加上O_TRUNC标志,则需要2~3min。(是因为截断文件长度需要很多时间??)

APUE上面写ext2文件系统并不支持O_SYNC,所以设置O_SYNC与否在写文件时间基本上没区别。
我机器上文件系统是ext4,可能还是不支持O_SYNC?

如果真的不支持,但是open(const char *pathname,O_SYNC)又显著地增加了写时间。

这是为什么呢?


O_SYNC保证要写到硬盘上的数据真正被硬盘收到以后才会返回,注意此时其实也不能保证硬盘真正将数据写到了磁盘上,因为硬盘内部还有缓存。在没有O_SYNC的时候,要写入磁盘的内容很可能被内核缓存在内存中,然后write函数就可以返回了,会快很多。缓存在内存中的数据会被内核在适当的时候写入硬盘。这就是时间上差别的主要来源。


我想你读的是apue 第二版, 在第三版中, Figure 3.13, 作者给出了linux/ext4, 从一个文件到另一个文件拷贝492.6MB的数据, buffer size 4096.

按照原文的说法:

In this case, the Linux operating system isn’t allowing us to set the O_SYNC flag using fcntl, instead failing without returning an error (but it would have honored the flag if we were able to specify it when the file was opened).

所以你的观察是对的, fcntl对O_SYNC不起作用, 在open时使用O_SYNC是起作用的. 按照文中的数据, write后跟fsync, 比不带fsync, clock time差不多增加一倍.

【热门文章】
【热门文章】