【发布时间】:2012-11-12 01:09:40
【问题描述】:
我们需要一个应用程序尽可能地保证当它报告一条记录时,它确实是持久的。我知道要做到这一点,您使用fsync(fd)。然而,出于某种奇怪的原因,使用 fsync() 似乎加快了写入磁盘的代码,而不是像预期的那样减慢它。
一些示例测试代码返回以下结果:
no sync() seconds:0.013388 writes per second:0.000001
sync() seconds:0.006268 writes per second:0.000002
下面是产生这些结果的代码:
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
void withSync() {
int f = open( "/tmp/t8" , O_RDWR | O_CREAT );
lseek (f, 0, SEEK_SET );
int records = 10*1000;
clock_t ustart = clock();
for(int i = 0; i < records; i++) {
write(f, "012345678901234567890123456789" , 30);
fsync(f);
}
clock_t uend = clock();
close (f);
printf(" sync() seconds:%lf writes per second:%lf\n", ((double)(uend-ustart))/(CLOCKS_PER_SEC), ((double)records)/((double)(uend-ustart))/(CLOCKS_PER_SEC));
}
void withoutSync() {
int f = open( "/tmp/t10" , O_RDWR | O_CREAT );
lseek (f, 0, SEEK_SET );
int records = 10*1000;
clock_t ustart = clock();
for(int i = 0; i < records; i++) {
write(f, "012345678901234567890123456789" , 30 );
}
clock_t uend = clock();
close (f);
printf("no sync() seconds:%lf writes per second:%lf \n", ((double)(uend-ustart))/(CLOCKS_PER_SEC), ((double)records)/((double)(uend-ustart))/(CLOCKS_PER_SEC));
}
int main(int argc, const char * argv[])
{
withoutSync();
withSync();
return 0;
}
【问题讨论】:
-
运行时是如此之小,以至于差异很可能来自执行环境中的差异。尝试一个需要几秒钟的测试用例并通过它运行两个版本。
-
文件缓存也起到了作用。例如,一些 UNIX 系统运行一个守护进程,flushd,它清理脏缓存页面。设置会影响您正在处理的内容以及它执行的频率。如果您想保证写入,则必须考虑环境
-
这两个函数在 Linux 上为我输出零时间。当我将记录数增加到 100 万条时,我得到了可衡量的时间量,但不同步版本要快一些。
-
/tmp是否与tmpfs一起挂载? -
由于“正确答案”是 cmets,我也以答案的形式添加答案。谢谢大家的反馈!
标签: c performance fsync