Linux学习之系统编程篇:mmap 内存映射区
(1)作用:將磁盤文件的數(shù)據(jù)映射內(nèi)存,用戶通過修改內(nèi)存就能修改磁盤文件。
(2)函數(shù)原型:
(3)參數(shù):共 6 個(前 4 個修飾映射區(qū),后 2 個修飾磁盤文件),分別為:
1)映射區(qū)首地址(addr): 我們不知道首地址,傳 NULL(但內(nèi)核知道),但我們可以通過返回值獲取。
2)映射區(qū)的大小(length): 不能為 0 (一般寫文件大小,但實際會擴充至 4k 的整數(shù)倍)。
3)映射區(qū)的權限(prot): PROT_READ 讀權限 ;PROT_WRITE 寫權限 (注意:必須要有讀權限)。
4)標志位參數(shù)(flags): MAP_SHARED 共享的 MAP_PRIVATE 私有的(注意:這個參數(shù)關系到內(nèi)存數(shù)據(jù)是否會同步到磁盤文件)。
5)文件描述符(fd): 怎么得到 fd? 先 open 獲得 (注意:必須包含讀權限)。
6)文件的偏移量(offset):注意必須是 4k 的整數(shù)倍,一般不偏移(寫 0)。
(4)返回值:
調(diào)用成功:返回映射區(qū)的首地址(viod*)。
調(diào)用失敗:返回一個 -1 的宏 。
(5)釋放內(nèi)存映射區(qū) munmap:
函數(shù)原型:
釋放成功返回 0, 釋放失敗返回 -1。
關于 mmap 有幾點注意:
(1)如果對映射區(qū)的首地址(創(chuàng)建 mmap 的返回值)進行 mem++,munmap 可不能釋放成功。
(2) 如果 open 時 O_RDONLY, mmap 時 PROT 參數(shù)指定 PROT_READ | PROT_WRITE 則mmap會調(diào)用失敗。
(3)如果文件偏移量為 1000 則 mmap 也會調(diào)用失敗,因為參數(shù)是無效的。偏移量必須是 4096 的整數(shù)倍。
(4)一定要檢測 mmap 的返回值,因為mmap 的坑很多,如果調(diào)用失敗,基本不知道失敗原因。
(5) mmap 在如下情況下會調(diào)用失敗:
參數(shù) 2 length = 0
參數(shù) 3 沒有指定 PROT_READ
參數(shù) 4 要考慮是否同步磁盤
參數(shù) 5 fd 打開權限小于映射區(qū)權限
參數(shù) 6 偏移量不是 4096 整數(shù)倍
(6)不能 open 的時候 O_CREAT 一個新文件來創(chuàng)建映射區(qū)嗎,因為創(chuàng)建一個新文件,文件大小為 0,會出現(xiàn)總線錯誤,若要創(chuàng)建,則創(chuàng)建后要擴展 ftruncate(fd, length)。
(7)文件描述符先關閉,對 mmap 映射沒有影響,只要通過 mmap 建立起磁盤文件和內(nèi)存映射區(qū)的關系后,文件描述符就沒有用了。
(8)對 mem 越界操作,如果越界的內(nèi)存被其他資源占用,會出現(xiàn)段錯誤。
(9)創(chuàng)建映射區(qū)的過程中,隱含著一次對映射文件的讀操作。 打開文件 open 一定要包含讀權限。
(10)對于 MAP_SHARED,要求:“文件打開的權限”小于等于“映射區(qū)的權限”;對于 MAP_PRIVATE 則無所謂,因為 mmap 中的權限是對內(nèi)存的限制。。
(11) 映射區(qū)的釋放與文件關閉無關。只要映射建立成功,文件可以立即關閉。。
(12)特別注意,當映射文件大小為 0 時,不能創(chuàng)建映射區(qū)。
所以:用于映射的文件必須要有實際大小!!(truncate)。
(13)mmap 使用時常常會出現(xiàn)總線錯誤,通常是由于共享文件存儲空間沒有對齊引起的。。
(14)munmap 傳入的地址一定是 mmap 的返回地址。堅決杜絕指針移動操作,否則會釋放失敗。。
(15) 文件偏移量必須為 4k 的整數(shù)倍。
(16) mmap 創(chuàng)建映射區(qū)出錯概率非常高,一定要檢查返回值,確保映射區(qū)建立成功再進行后續(xù)操作。
總結(jié)
以上是生活随笔為你收集整理的Linux学习之系统编程篇:mmap 内存映射区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习之系统编程篇:fifo
- 下一篇: Linux学习之系统编程篇:mmap练习