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);
}

Linux direct io使用例子的更多相关文章

  1. MMAP和DIRECT IO区别

    看完此文,题目不言自明.转自 http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术人员非常关 ...

  2. Linux的io机制

    Linux的io机制 Buffered-IO 和Direct-IO Linux磁盘I/O分为Buffered IO和Direct IO,这两者有何区别呢? 对于Buffered IO: 当应用程序尝试 ...

  3. MMAP和DIRECT IO区别【转】

    转自:http://www.cnblogs.com/zhaoyl/p/5901680.html 看完此文,题目不言自明.转自 http://blog.chinaunix.net/uid-2710571 ...

  4. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  5. Linux磁盘IO监控[zz]

    磁盘 I/O 监控是 Unix/Linux 系统管理中一个非常重要的组成部分.它可以监控吞吐量.每秒 I/O 数.磁盘利用率.服务时间等信息,并且在发现异常时,发送告警信息给系统管理员,便于系统管理员 ...

  6. Linux Network IO Model、Socket IO Model - select、poll、epoll

    目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...

  7. Linux的IO调度

    Linux的IO调度 IO调度发生在Linux内核的IO调度层.这个层次是针对Linux的整体IO层次体系来说的.从read()或者write()系统调用的角度来说,Linux整体IO体系可以分为七层 ...

  8. 通过iostat来查看linux硬盘IO性能|实例分析

    iostat查看linux硬盘IO性能 rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/s wrqm/s: 每秒进行 merge 的写操作数目.即 delta(wm ...

  9. bufferIO,Direct io,mmap, ZeroCopy

    1 bufferIO(传统IO),Direct io(干掉内核cache),mmap(大数据映射),zeroCopy(网络IO) 2 linux 5种IO 3NIO 相关知识 这张图展示了mmap() ...

随机推荐

  1. 对于Linux内核tty设备的一点理解

    http://blog.chinaunix.net/uid-7828352-id-3233064.html

  2. jenkins下载插件失败解决办法

  3. Android动态逆向分析工具ZjDroid--脱壳神器

    项目地址:https://github.com/BaiduSecurityLabs/ZjDroid 前提条件: 1.Root手机一部 2.须要通过Xposed installer( http://dl ...

  4. jQuery总结02

    1 如何搭建一个 jQuery 环境? 2 jQuery 对象与 DOM 对象一样吗?区别是什么? 3 jQuery选择器类型有哪些?

  5. linux驱动注册汇总

    --- 01)TP file_operations: { 1. static struct file_operations tpd_fops = { // .owner = THIS_MODULE, ...

  6. C++ Web 编程(菜鸟教程)

    C++ Web 编程(菜鸟教程) C++ Web 编程 什么是 CGI? 公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的. CGI 规范目前是由 NC ...

  7. 自适应阈值分割—大津法(OTSU算法)C++实现

    大津法是一种图像灰度自适应的阈值分割算法,是1979年由日本学者大津提出,并由他的名字命名的.大津法按照图像上灰度值的分布,将图像分成背景和前景两部分看待,前景就是我们要按照阈值分割出来的部分.背景和 ...

  8. 【POJ 3074】 Sudoku

    [题目链接] http://poj.org/problem?id=3074 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 转化方法如下 : 我们知道,在一个数独中 : 1. ...

  9. hdu 3037Saving Beans(卢卡斯定理)

    Saving Beans Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  10. 网络流模板(模板题:POJ1273)

    模板题:POJ1273 EK: #include <queue> #include <cstdio> #include <cstring> #include < ...