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的倍數