• Linux direct io使用例子


    Linux direct io使用

    在linux 2.6内核上使用direct io不难,只需按照如下几点来做即可:

    1,在open文件时加上O_DIRECT旗标,这样以通告内核我们想对该文件进行直接io操作。

    2,在源文件的最顶端加上_GNU_SOURCE宏定义,或在编译时加在命令行上也可以,否则将提示:

    direct_io_write_file.c: In function 'main':
    direct_io_write_file.c:25: error: 'O_DIRECT' undeclared (first use in this function)
    direct_io_write_file.c:25: error: (Each undeclared identifier is reported only once
    direct_io_write_file.c:25: error: for each function it appears in.)
    

    3,存放文件数据的缓存区起始位置以及每一次读写数据长度必须是磁盘逻辑块大小的整数倍,一般也就是512字节(也有可能是一内存页大小,4096),否则将导致read/write失败,perror将提示:read failed: Invalid argument或write failed: Invalid argument。
    1和2很容易做到,而第3点,要满足缓存区起始位置与512对齐,这可以在进行缓存区空间申请时使用posix_memalign这样的函数指定512对齐:

    ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
    

    或者进行手动调节对齐:

    real_buf = malloc(BUF_SIZE + 512);
    aligned_buf = ((((unsigned int)real_buf + 512 - 1) / 512) * 512);
    

    由于要满足每一次读写数据长度必须是磁盘逻辑块大小的整数倍,所以最后一次文件操作可能无法满足,此时只能重新以cached io模式打开文件后,fseek到对应位置进行剩余数据的读写。
    为什么要使用direct io?因为direct io不过文件系统缓冲,也就是说对文件进行direct io操作不会减少系统的free内存数量,这对于自己本身带有缓存的应用程序(比如数据库)比较有用。
    示例:

    /**
     * gcc cached_io_read_file.c -o cached_io_read_file -D_GNU_SOURCE
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    #include <string.h>
    #define BUF_SIZE 1024
     
    int main()
    {
        int fd;
        int ret;
        unsigned char *buf;
        ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
        if (ret) {
            perror("posix_memalign failed");
            exit(1);
        }
     
        fd = open("./direct_io.data", O_RDONLY, 0755);
        if (fd < 0){
            perror("open ./direct_io.data failed");
            free(buf);
            exit(1);
        }
     
        do {
            ret = read(fd, buf, BUF_SIZE);
            if (ret < 0) {
                perror("read ./direct_io.data failed");
            }
        } while (ret > 0);
         
        free(buf);
        close(fd);
    }
     
    
    /**
     * gcc cached_io_write_file.c -o cached_io_write_file -D_GNU_SOURCE
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    #include <string.h>
    #define BUF_SIZE 1024
     
    int main(int argc, char * argv[])
    {
        int fd;
        int ret;
        unsigned char *buf;
        ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
        if (ret) {
            perror("posix_memalign failed");
            exit(1);
        }
        memset(buf, 'c', BUF_SIZE);
     
        fd = open("./direct_io.data", O_WRONLY | O_CREAT, 0755);
        if (fd < 0){
            perror("open ./direct_io.data failed");
            free(buf);
            exit(1);
        }
     
        do {
            ret = write(fd, buf, BUF_SIZE);
            if (ret < 0) {
                perror("write ./direct_io.data failed");
            }
        } while (1);
     
        free(buf);
        close(fd);
    }
    
     
    /**
     * gcc direct_io_read_file.c -o direct_io_read_file -D_GNU_SOURCE
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    #include <string.h>
    #define BUF_SIZE 1024
     
    int main()
    {
        int fd;
        int ret;
        unsigned char *buf;
        ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
        if (ret) {
            perror("posix_memalign failed");
            exit(1);
        }
     
        fd = open("./direct_io.data", O_RDONLY | O_DIRECT, 0755);
        if (fd < 0){
            perror("open ./direct_io.data failed");
            exit(1);
        }
     
        do {
            ret = read(fd, buf, BUF_SIZE);
            if (ret < 0) {
                perror("write ./direct_io.data failed");
            }
        } while (ret > 0);
         
        free(buf);
        close(fd);
    }
    
     
    /**
     * gcc direct_io_write_file.c -o direct_io_write_file -D_GNU_SOURCE
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    #include <string.h>
    #define BUF_SIZE 1024
     
    int main(int argc, char * argv[])
    {
        int fd;
        int ret;
        unsigned char *buf;
        ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
        if (ret) {
            perror("posix_memalign failed");
            exit(1);
        }
        memset(buf, 'c', BUF_SIZE);
     
        fd = open("./direct_io.data", O_WRONLY | O_DIRECT | O_CREAT, 0755);
        if (fd < 0){
            perror("open ./direct_io.data failed");
            exit(1);
        }
     
        do {
            ret = write(fd, buf, BUF_SIZE);
            if (ret < 0) {
                perror("write ./direct_io.data failed");
            }
        } while (1);
     
        free(buf);
        close(fd);
    }
    
    /**
     * gcc direct_io_read_write_file.c -o direct_io_read_write_file -D_GNU_SOURCE
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h> 
    #include <string.h>
    #define BUF_SIZE 1024
     
    int main(int argc, char * argv[])
    {
        int fd, fd1;
        int ret;
        unsigned char *buf;
        ret = posix_memalign((void **)&buf, 512, BUF_SIZE);
        if (ret) {
            perror("posix_memalign failed");
            exit(1);
        }
        memset(buf, 'c', BUF_SIZE);
     
        fd = open("/dev/sda", O_RDONLY | O_DIRECT | O_LARGEFILE, 0755);
        if (fd < 0){
            perror("open /dev/sda failed");
            exit(1);
        }
     
        fd1 = open("./direct_io.data", O_WRONLY | O_DIRECT | O_CREAT, 0755);
        if (fd1 < 0){
            perror("open ./direct_io.data failed");
            close(fd);
            exit(1);
        }
     
        do {
            ret = read(fd, buf, BUF_SIZE);
            if (ret < 0) {
                perror("read /dev/sda failed");
            }
            ret = write(fd1, buf, BUF_SIZE);
            if (ret < 0) {
                perror("write ./direct_io.data failed");
            }
        } while (1);
     
        free(buf);
        close(fd);
        close(fd1);
    }
    
  • 相关阅读:
    第十章、数据库运行维护与优化
    第九章、安全管理
    第八章、数据库后台编程技术
    第七章、高级数据库查询
    第六章、数据库及数据库对象
    第五章、UML与数据库应用系统
    第四章、数据库应用系统功能设计与实施
    struts2标签debug
    SSH框架 more than one namespace has been specificed without a prefix
    Http Status 404
  • 原文地址:https://www.cnblogs.com/muahao/p/7903230.html
Copyright © 2020-2023  润新知