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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章