APUE中fcntl.h的使用及O_SYNC在Mac与Ubuntu下的测试

此部分测试涉及到APUE V3中,第三章的图3-12到图3-14。

通过fcntl.h提供的功能,修改fd的文件属性,本处增加O_SYNC功能,并测试其效果。

本文涉及代码:

tree ch3
ch3
├── makefile.sync
├── mycat.c
├── set_fl.c
├── set_fl.h
├── sync.c
└── test

 

1 不使用O_SYNC功能

mycat.c 代码:

 1 #include "../apue.h"
 2 
 3 #define BUFFSIZE 4096
 4 
 5 int main(void)
 6 {
 7     int  n;
 8     char    buf[BUFFSIZE];
 9     // set_fl(STDOUT_FILENO, O_SYNC);   for O_SYNC 
10     while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
11         if (write(STDOUT_FILENO, buf, n) != n)
12             err_sys("write error");
13 
14     if (n < 0)
15         err_sys("read error");
16 
17     exit(0);
18 }

 

2 使用O_SYNC功能的代码

set_fl.h头文件:

#ifndef SET_FL
#define SET_FL

void
set_fl(int fd, int flags);
/* flags are file status flags to turn on */

void
clr_fl(int fd, int flags);
/* flags are file status flags to turn off */

#endif

set_fl.c代码:

#include <fcntl.h>
#include "set_fl.h"

void set_fl(int fd, int flags) 
/* flags are file status flags to turn on */
{
    int  val;

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

    val |= flags;        /* turn on flags */

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

sync.c代码,即前面mycat.c中,取消set_fl函数 的注释。

makefile.sync文件:

sync: sync.o set_fl.o
    gcc -o sync  sync.o set_fl.o

set_fl.o: set_fl.c
    gcc -c set_fl.c

3 测试对比

准备:分别在mac及ubuntu环境下生成一个1GB的文件,并编译文件。

dd if=/dev/zero of=./test bs=512 count=2048000
 2048000+0 records in
 2048000+0 records out
 1048576000 bytes (1.0 GB) copied, 11.1418 s, 94.1 MB/s

make -f makefile.sync

gcc mycat.c

Ubuntu14.04效果如下:

time ./a.out < test >./dup.buf
 real    0m9.965s
 user    0m0.014s
 sys 0m1.453s

time ./sync < test >./dup.sync
 real    0m10.355s
 user    0m0.025s
 sys 0m1.350s

mac10.11效果:

time ./a.out < test >/dev/null
./a.out < test > /dev/null  0.10s user 1.17s system 60% cpu 2.079 total

time ./sync < test >/dev/null
./sync < test > /dev/null  0.10s user 1.20s system 62% cpu 2.070 total

time ./sync < test >./dup.sync
./sync < test > ./dup.sync  0.27s user 23.79s system 45% cpu 53.369 total

time ./a.out < test >./dup.buf
./a.out < test > ./dup.buf  0.11s user 3.06s system 53% cpu 5.955 total

可见,每一次buf数据都直接O_SYNC到磁盘,会影响写磁盘的效果,在mac上几乎近10倍的差异。

而在Ubuntu上,却没有特别明显的差异,如书上所述。通过fcntl对O_SYNC的控制是失效的。

#over

本文源代码链接。

 

你可能感兴趣的:(APUE中fcntl.h的使用及O_SYNC在Mac与Ubuntu下的测试)