Linux系統編程 共享內存 mmap

1.mmap函數介紹

void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

返回:成功:返回創建的映射區首地址;失敗:MAP_FAILED 宏
參數:

addr: 建設映射區的首地址,由Linux內核指定,使用時,直接傳遞NULL
length:欲創建映射區的大小
prot:映射區權限 PROT_READ、PROT_WRITE、PROT_READ | PROT_WAITE (讀寫)
flags: 標誌位參數 (常用於設定更新物理區域、設置共享、創建匿名映射區)
MAP_SHARED: 會將映射區所做的操作反映到物理設備(磁盤)上
MAP_PRIVATE: 映射區所做的修改不會反映到物理設備
fd: 用來建立映射區的文件描述符
offset: 映射文件的偏移(4k 的整數倍) (映射一部分)

2.mmap實踐

1.打開一個文件(或者穿件一個新文件),
2.用mmap函數,創建內存映射區(參數MAP_SHARED,會反映到映射區)
3.通過指針p,向內存映射區寫入數據
4.關閉映射區,關閉文件

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

int main()
{         
        int len, ret;
        char *p = NULL;
        int fd = open("mytest.txt",O_CREAT|O_RDWR,0644);//打開文件
        if(fd < 0){ 
                perror("open error:");
                exit(1);
        }
        len = ftruncate(fd,4);
        if( len == -1 ){        
                perror("ftruncate error:");
                exit(1);
        } 
        //泛型指針可以和任意的指針類型,完成隱式轉換
        p = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);//創建映射區
        if (p == MAP_FAILED){   
                perror("mmap error:");
                exit(1);
        }
        strcpy(p , "abc"); //模擬p指針向內存寫數據
        ret = munmap(p, 4);
        if(ret == -1){
                perror("munmap error:");
                exit(1);
        }

        close(fd);//關閉文件

        return 0;
}
         

5.結果,是mytest.txt文件中,有寫入的數據 “abc”
在這裏插入圖片描述

3.mmap相關問題

0.可以open的時候 O_CREAT一個新文件來創建映射區嗎?
可以,上面的代碼就是以 O_CREAT 一個新文件來創建映射區的。
1.可不可以創建大小爲0的映射區呢?不可以
在這裏插入圖片描述
在這裏插入圖片描述

2.如果p++ ,munmap可否成功?

在這裏插入圖片描述
在這裏插入圖片描述
不能成功,因爲munmap 回收時,要傳入映射區的首地址

3.如果open時O_RDONLY,mmap時PROT參數指定PROT_READ | PROT_WRITE 會怎樣?

不行,權限不夠,映射區無寫權限。
在這裏插入圖片描述在這裏插入圖片描述

若mmap函數flags參數修改爲 MAP_PRIVATE,會出現總線錯誤,由於硬件異常導致的,和實際空間大小和訪問權限有關。
在這裏插入圖片描述

若mmap函數flags參數修改爲 MAP_SHARED,以只寫方式打開文件,以只寫方式創建映射區。

在這裏插入圖片描述
在這裏插入圖片描述

若都修改爲只讀
在這裏插入圖片描述
在這裏插入圖片描述

結論:1.創建映射區的權限,小於等於文件打開的權限
2.創建映射區的過程,隱含着對文件的讀操作

3.如果文件偏移量爲1000會怎樣?

不行,必須是4k的整數倍(一頁的大小)。映射區是MMU幫助完成映射,所以爲4k的倍數

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