MMAP-存儲(chǔ)映射I/O

存儲(chǔ)映射I/O 介紹

????存儲(chǔ)映射IO(Memory-mapped I/O) 使用一個(gè)磁盤文件與存儲(chǔ)空間的一個(gè)緩沖區(qū)相映射。于是當(dāng)緩沖區(qū)中取出數(shù)據(jù)篮奄,就相當(dāng)于讀文件中的相應(yīng)字節(jié)捆愁。于此類似。間數(shù)據(jù)存入緩沖區(qū)窟却,則相應(yīng)的字節(jié)就會(huì)自動(dòng)寫入文件昼丑。因?yàn)閿?shù)據(jù)已經(jīng)寫入文件,即使機(jī)器重啟數(shù)據(jù)還在夸赫。


TIM截圖20190517162610.png

mmap函數(shù)

????使用這種方法菩帝,首先應(yīng)通知內(nèi)核,間一個(gè)指定文件映射到存儲(chǔ)區(qū)域中茬腿⌒哺剑可以通過mmap函數(shù)來實(shí)現(xiàn)。

函數(shù)原型 :
    void *mmap(void *adrr, size_t length, int prot, int flags, int fd, off_t offset); 
參數(shù):
    addr:建立映射區(qū)的首地址滓彰,有Linux內(nèi)核指定控妻。使用時(shí)傳NULL即可
    length:與創(chuàng)建映射取的大小
    prot: 映射區(qū)權(quán)限PROT_READ、PROT_WRITE揭绑、PROT_READ|PROT_WRITE
    flags:標(biāo)志位參數(shù)(常用于設(shè)定更新物理區(qū)域弓候、設(shè)置共享、創(chuàng)建匿名映射區(qū))
            MAP_SHARED:  會(huì)將映射區(qū)所做的操作反映到物理設(shè)備(磁盤)上他匪。
            MAP_PRIVATE: 映射區(qū)所做的修改不會(huì)反映到物理設(shè)備菇存。
   fd: 用來建立映射區(qū)的文件描述符
   offset: 映射文件的偏移(4k的整數(shù)倍)

munmap函數(shù)

當(dāng)不需要這個(gè)映射內(nèi)存時(shí)通過munmap函數(shù)來釋放

函數(shù)原型:
    int munmap(void *addr, size_t length);
參數(shù):
    addr :mmap的返回值
    length:釋放區(qū)域的長度

示例代碼

mem.txt文件

jjjjjjjj

mmap.c文件

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

int main()
{
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

int main()
{
    int fd = open("mem.txt",O_RDWR);//創(chuàng)建并且截?cái)辔募?    //int fd = open("mem.txt",O_RDWR|O_CREAT|O_TRUNC,0664);//創(chuàng)建并且截?cái)辔募?

    //創(chuàng)建映射區(qū)
   char *mem = mmap(NULL,20,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    //char *mem = mmap(NULL,8,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);

    if(mem == MAP_FAILED){
        perror("mmap err");
        return -1;
    }
  
    //拷貝數(shù)據(jù)
    strcpy(mem,"helloworld");
//    mem++;
    //釋放mmap
    if(munmap(mem,20) < 0){
        perror("munmap err");
    }
    close(fd);
    return 0;
}

運(yùn)行代碼之后,發(fā)現(xiàn)mem.txt文件內(nèi)容已經(jīng)改變

[root@VM_0_11_centos linux]# cat mem.txt
helloworl[root@VM_0_11_centos linux]#

**讀寫例 **

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/wait.h>

typedef struct _Student{
    int sid;
    char sname[20];
}Student;

int main(int argc,char *argv[])
{
    //open file 
    int fd = open(argv[1],O_RDWR);
    //mmap 
    int length = sizeof(Student);
    Student *stu = mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(stu == MAP_FAILED){
        perror("mmap err");
        return -1;
    }
    //read data 
    while(1){
        printf("sid=%d,sname=%s\n",stu->sid,stu->sname);
        sleep(1);
    }
    //close and munmap 
    munmap(stu,length);
    close(fd);
    return 0;
}

寫示例

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/wait.h>

typedef struct  _Student{
    int sid;
    char sname[20];
}Student;

int main(int argc,char *argv[])
{
    if(argc != 2){
        printf("./a.out filename\n");
        return -1;
    }
    
    // 1. open file 
    int fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);
    int length = sizeof(Student);

    ftruncate(fd,length);

    // 2. mmap
    Student * stu = mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    
    if(stu == MAP_FAILED){
        perror("mmap err");
        return -1;
    }
    int num = 1;
    // 3. 修改內(nèi)存數(shù)據(jù)
    while(1){
        stu->sid = num;
        sprintf(stu->sname,"xiaoming-%03d",num++);
        sleep(1);//相當(dāng)于沒隔1s修改一次映射區(qū)的內(nèi)容
    }
    // 4. 釋放映射區(qū)和關(guān)閉文件描述符
    munmap(stu,length);
    close(fd);

    return 0;
}

map的一些問題

1.如果對(duì)mem越界操作會(huì)怎樣邦蜜?

多出的數(shù)據(jù)會(huì)丟失依鸥,盡量避免這樣的操作

2.如果文件描述符向關(guān)閉,對(duì)mmap映射有沒有影響

沒有影響

3.open的時(shí)候悼沈,可以新創(chuàng)建一個(gè)文件來創(chuàng)建映射區(qū)嗎贱迟?

不可以姐扮,使用的文件大小不能為0

4.如果文件偏移隨便填一個(gè)數(shù)會(huì)怎么樣?

運(yùn)行時(shí)會(huì)報(bào)錯(cuò)

匿名映射

???? 通過使用我們發(fā)現(xiàn)衣吠,使用映射區(qū)來完成文件讀寫十分方便茶敏,賦值進(jìn)程通信也比較容易。但是缺陷是缚俏,每次創(chuàng)建映射區(qū)一定要依賴一個(gè)文件才能實(shí)現(xiàn)惊搏。通常為了建立映射區(qū)要open一個(gè)temp文件,創(chuàng)建好了再unlink,close掉忧换,比較麻煩恬惯。可以直接使用匿名映射來代替亚茬。Linux系統(tǒng)給我們提供了創(chuàng)建匿名映射區(qū)的方法酪耳,無需依賴一個(gè)文件,即可創(chuàng)建映射取才写。同樣需要借助標(biāo)志位參數(shù)flags來指定葡兑。
示例代碼:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/wait.h>

int main()
{
    //修改創(chuàng)建的參數(shù)
    int *mem = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);

    if(mem == MAP_FAILED){
        perror("mmap err");
        return -1;
    }
    ...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赞草,隨后出現(xiàn)的幾起案子讹堤,更是在濱河造成了極大的恐慌,老刑警劉巖厨疙,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洲守,死亡現(xiàn)場離奇詭異,居然都是意外死亡沾凄,警方通過查閱死者的電腦和手機(jī)梗醇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撒蟀,“玉大人叙谨,你說我怎么就攤上這事”M停” “怎么了手负?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長姑尺。 經(jīng)常有香客問我竟终,道長,這世上最難降的妖魔是什么切蟋? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任统捶,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喘鸟。我一直安慰自己匆绣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布迷守。 她就那樣靜靜地躺著犬绒,像睡著了一般旺入。 火紅的嫁衣襯著肌膚如雪兑凿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天茵瘾,我揣著相機(jī)與錄音礼华,去河邊找鬼。 笑死拗秘,一個(gè)胖子當(dāng)著我的面吹牛圣絮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雕旨,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼扮匠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凡涩?” 一聲冷哼從身側(cè)響起棒搜,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎活箕,沒想到半個(gè)月后力麸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡育韩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年克蚂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筋讨。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埃叭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悉罕,到底是詐尸還是另有隱情赤屋,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布蛮粮,位于F島的核電站益缎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏然想。R本人自食惡果不足惜莺奔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧令哟,春花似錦恼琼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狠半,卻和暖如春噩死,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背神年。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工已维, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人已日。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓垛耳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親飘千。 傳聞我的和親對(duì)象是個(gè)殘疾皇子堂鲜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • UNIX網(wǎng)絡(luò)編程第二卷進(jìn)程間通信對(duì)mmap函數(shù)進(jìn)行了說明。該函數(shù)主要用途有三個(gè):1护奈、將一個(gè)普通文件映射到內(nèi)存中缔莲,通...
    宇文黎琴閱讀 3,491評(píng)論 0 4
  • 一、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運(yùn)行的地址不確定 關(guān)于...
    SeanCST閱讀 7,784評(píng)論 0 27
  • 一逆济、基礎(chǔ)知識(shí):1酌予、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,369評(píng)論 0 4
  • mmap基礎(chǔ)概念 mmap是一種內(nèi)存映射文件的方法奖慌,即將一個(gè)文件或者其它對(duì)象映射到進(jìn)程的地址空間抛虫,實(shí)現(xiàn)文件磁盤地址...
    神奇的考拉閱讀 2,181評(píng)論 3 6
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,093評(píng)論 1 32