O_DIRECT使用

使用O_DIRECT的话,就必须以页为单位进行I/O

O_DIRECT undeclared

加宏 #define _GUN_SOURCE

Page cache这种内核提供的缓存机制并不是强制使用的,如果进程在open()一个文件的时候指定flags为O_DIRECT,那进程和这个文件的数据交互就直接在用户提供的buffer和磁盘之间进行,page cache就被bypass了,借用硬件cache的术语就是uncachable,这种文件访问方式被称为direct I/O,适用于用户使用自己设备提供的缓存机制的场景,比如某些数据库应用

O_DIRECT只是绕过了page cache,但它并不等待数据真正写到了磁盘上。open()中flags参数使用O_SYNC才能保证writepage()会等到数据可靠的写入磁盘后再返回,适用于某些不容许数据丢失的关键应用。O_SYNC模式下可以使用或者不使用page cache,如果使用page cache,则相当于硬件cache的write through机制

即使用fd=open(s, O_RDWR | O_CREAT | O_DIRECT | O_SYNC);

本文参考:

http://blog.csdn.net/wallwind/article/details/7461701

首先来看O_DIRECT参数适用要求:

O_DIRECT
    Try to minimize cache effects of the I/O to and from this file. In general this will degrade performance, but it is useful in special situations, such as when applications do their own caching. File I/O is done directly to/from user space buffers. The I/O is synchronous, i.e., at the completion of a read(2) or write(2), data is guaranteed to have been transferred. Under Linux 2.4 transfer sizes, and the alignment of user buffer and file offset must all be multiples of the logical block size of the file system. 

上述也就是说buffer的地址以及大小都必须是block size 的整数倍,buffer的大小可以通过代码设定,但buffer的首地址的控制,需要通过posix_menalign()函数来数据对齐

ps:上述所说的buffer地址为block size整数倍,就是数据对齐的概念

int posix_memalign (void **memptr, size_t alignment, size_t size);

成功会返回size字节的动态内存,且内存地址为alignment的整数倍

下面看具体代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define __USE_GNU
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <pwd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
 
int  main( void )
{
     int         fd;
     int         i;
     const int   SIZE = 4096 * 10 ; //(每次写入文件数据块大小)
     char*       buffer;
     char s[ 100 ];  
     int pagesize=getpagesize();
     printf( "pagesize = %d\n" ,pagesize);
    pid_t my_pid;
     my_pid=getpid();
     printf( "%d\n" ,my_pid);
     if (mkdir( "dir1" ,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH)< 0 ) //创建新目录
     {
         printf( "mkdir failed\n" );
         return - 1 ;     
     }
     if ( 0 != posix_memalign(( void **)&buffer, 4096 , 40960 )){
                 printf( "Errori in posix_memalign\n" );
     }
     for (i= 0 ;i< 10 ;i++)
     {
         sprintf(s, "./dir1/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%d.txt" ,i);
         printf( "%s\n" ,s);
         fd=open(s, O_RDWR | O_CREAT | O_DIRECT);
         write(fd,buffer,SIZE);
                 fsync(fd);
         close(fd);
     }
     free(buffer);
     sync();
     return 0 ;
}

上述代码有几个点:

1.mkdir创建目录

2.posix_menalign()进行数据对齐

3.获取block size,即内存页大小getpagesize()

4.编译时需要gcc -o blktrace_study1 blktrace_study1.c -D_GNU_SOURCE 

5.open函数返回的为int ,区别fopen函数返回FILE *

6.fsync和sync区别见另一篇博客

参考:http://sundayhut.is-programmer.com/posts/50419.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值