博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux direct io使用例子
阅读量:6265 次
发布时间:2019-06-22

本文共 4862 字,大约阅读时间需要 16 分钟。

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 oncedirect_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 
#include
#include
#include
#include
#include
#include
#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 
#include
#include
#include
#include
#include
#include
#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 
#include
#include
#include
#include
#include
#include
#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 
#include
#include
#include
#include
#include
#include
#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 
#include
#include
#include
#include
#include
#include
#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);}

转载于:https://www.cnblogs.com/muahao/p/7903230.html

你可能感兴趣的文章
网卡驱动
查看>>
kinect sdk开发入门WPFdemo笔记
查看>>
Server.Transfer详细解释
查看>>
java单链表的增、删、查操作
查看>>
The working copy at 'xxx' is too old 错误解决
查看>>
jadclipse
查看>>
// 1.什么是JOSN?
查看>>
SQL语句详细汇总
查看>>
如何保护.net中的dll文件(防破解、反编译)
查看>>
Python 装饰器
查看>>
Docker 网络模式
查看>>
[POI2013]Usuwanka
查看>>
problem-solving-with-algorithms-and-data-structure-usingpython(使用python解决算法和数据结构) -- 算法分析...
查看>>
nodejs + CompoundJS 资源
查看>>
转:C#并口热敏小票打印机打印位图
查看>>
scau 17967 大师姐唱K的固有结界
查看>>
spring之<bean>实例化
查看>>
hereim_美句_2
查看>>
蓝桥杯2017国赛JAVAB组 填字母游戏 题解
查看>>
25.安装配置phantomjs
查看>>