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)又显著地增加了写时间。
这是为什么呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想你读的是apue 第二版, 在第三版中, Figure 3.13, 作者给出了linux/ext4, 从一个文件到另一个文件拷贝492.6MB的数据, buffer size 4096.
按照原文的说法:
所以你的观察是对的, fcntl对O_SYNC不起作用, 在open时使用O_SYNC是起作用的. 按照文中的数据, write后跟fsync, 比不带fsync, clock time差不多增加一倍.
O_SYNC保证要写到硬盘上的数据真正被硬盘收到以后才会返回,注意此时其实也不能保证硬盘真正将数据写到了磁盘上,因为硬盘内部还有缓存。在没有O_SYNC的时候,要写入磁盘的内容很可能被内核缓存在内存中,然后write函数就可以返回了,会快很多。缓存在内存中的数据会被内核在适当的时候写入硬盘。这就是时间上差别的主要来源。