• 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

    本文源代码链接

  • 相关阅读:
    flutter Sliver滑动视图组件
    Ionic4.x、Cordova Android 检测应用版本号、服务器下载文件以及实现App自动升级、安装
    flutter SnackBar 底部消息提示
    Flutter ExpansionPanel 可展开的收缩控件
    Ionic4 Cordova 调用原生硬件 Api 实现扫码功能
    Flutter BottomSheet底部弹窗效果
    Flutter 中AlertDialog确认提示弹窗
    Ionic Cordova 调用原生 Api 实现拍照上传 图片到服务器功能
    Flutter 中SimpleDialog简单弹窗使用
    Springboot项目mysql日期存储不匹配问题和在idea本地可以运行起来,但打包jar后运行报找不到mysql驱动的解决方案
  • 原文地址:https://www.cnblogs.com/qinqiao/p/5059470.html
Copyright © 2020-2023  润新知