华南俳烁实业有限公司

考試首頁 | 考試用書 | 培訓(xùn)課程 | 模擬考場 | 考試論壇  
  當(dāng)前位置:操作系統(tǒng) > Unix > 文章內(nèi)容
  

Linux內(nèi)存管理之mmap詳解:mmap系統(tǒng)調(diào)用

 [ 2017年1月20日 ] 【

mmap系統(tǒng)調(diào)用

1. mmap系統(tǒng)調(diào)用    

    mmap將一個文件或者其它對象映射進(jìn)內(nèi)存。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會清零。munmap執(zhí)行相反的操作,刪除特定地址區(qū)域的對象映射。

當(dāng)使用mmap映射文件到進(jìn)程后,就可以直接操作這段虛擬地址進(jìn)行文件的讀寫等操作,不必再調(diào)用read,write等系統(tǒng)調(diào)用.但需注意,直接對該段內(nèi)存寫時不會寫入超過當(dāng)前文件大小的內(nèi)容.

采用共享內(nèi)存通信的一個顯而易見的好處是效率高,因為進(jìn)程可以直接讀寫內(nèi)存,而不需要任何數(shù)據(jù)的拷貝。對于像管道和消息隊列等通信方式,則需要在內(nèi)核和用戶空間進(jìn)行四次的數(shù)據(jù)拷貝,而共享內(nèi)存則只拷貝兩次數(shù)據(jù):一次從輸入文件到共享內(nèi)存區(qū),另一次從共享內(nèi)存區(qū)到輸出文件。實際上,進(jìn)程之間在共享內(nèi)存時,并不總是讀寫少量數(shù)據(jù)后就解除映射,有新的通信時,再重新建立共享內(nèi)存區(qū)域。而是保持共享區(qū)域,直到通信完畢為止,這樣,數(shù)據(jù)內(nèi)容一直保存在共享內(nèi)存中,并沒有寫回文件。共享內(nèi)存中的內(nèi)容往往是在解除映射時才寫回文件的。因此,采用共享內(nèi)存的通信方式效率是非常高的。  

    基于文件的映射,在mmap和munmap執(zhí)行過程的任何時刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情況下沒有得到更新,首次對映射區(qū)的第一個頁索引時會更新該字段的值。用PROT_WRITE 和 MAP_SHARED標(biāo)志建立起來的文件映射,其st_ctime 和 st_mtime在對映射區(qū)寫入之后,但在msync()通過MS_SYNC 和 MS_ASYNC兩個標(biāo)志調(diào)用之前會被更新。

用法:

#include 

void *mmap(void *start, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *start, size_t length);

返回說明:

成功執(zhí)行時,mmap()返回被映射區(qū)的指針,munmap()返回0。失敗時,mmap()返回MAP_FAILED[其值為(void *)-1],munmap返回-1。errno被設(shè)為以下的某個值

EACCES:訪問出錯

EAGAIN:文件已被鎖定,或者太多的內(nèi)存已被鎖定

EBADF:fd不是有效的文件描述詞

EINVAL:一個或者多個參數(shù)無效

ENFILE:已達(dá)到系統(tǒng)對打開文件的限制

ENODEV:指定文件所在的文件系統(tǒng)不支持內(nèi)存映射

ENOMEM:內(nèi)存不足,或者進(jìn)程已超出最大內(nèi)存映射數(shù)量

EPERM:權(quán)能不足,操作不允許

ETXTBSY:已寫的方式打開文件,同時指定MAP_DENYWRITE標(biāo)志

SIGSEGV:試著向只讀區(qū)寫入

SIGBUS:試著訪問不屬于進(jìn)程的內(nèi)存區(qū)

參數(shù):

start:映射區(qū)的開始地址。


length:映射區(qū)的長度。


prot:期望的內(nèi)存保護(hù)標(biāo)志,不能與文件的打開模式?jīng)_突。是以下的某個值,可以通過or運算合理地組合在一起

PROT_EXEC //頁內(nèi)容可以被執(zhí)行

PROT_READ //頁內(nèi)容可以被讀取

PROT_WRITE //頁可以被寫入

PROT_NONE //頁不可訪問


flags:指定映射對象的類型,映射選項和映射頁是否可以共享。它的值可以是一個或者多個以下位的組合體

MAP_FIXED //使用指定的映射起始地址,如果由start和len參數(shù)指定的內(nèi)存區(qū)重疊于現(xiàn)存的映射空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。并且起始地址必須落在頁的邊界上。

MAP_SHARED //與其它所有映射這個對象的進(jìn)程共享映射空間。對共享區(qū)的寫入,相當(dāng)于輸出到文件。直到msync()或者munmap()被調(diào)用,文件實際上不會被更新。

MAP_PRIVATE //建立一個寫入時拷貝的私有映射。內(nèi)存區(qū)域的寫入不會影響到原文件。這個標(biāo)志和以上標(biāo)志是互斥的,只能使用其中一個。

MAP_DENYWRITE //這個標(biāo)志被忽略。

MAP_EXECUTABLE //同上

MAP_NORESERVE //不要為這個映射保留交換空間。當(dāng)交換空間被保留,對映射區(qū)修改的可能會得到保證。當(dāng)交換空間不被保留,同時內(nèi)存不足,對映射區(qū)的修改會引起段違例信號。

MAP_LOCKED //鎖定映射區(qū)的頁面,從而防止頁面被交換出內(nèi)存。

MAP_GROWSDOWN //用于堆棧,告訴內(nèi)核VM系統(tǒng),映射區(qū)可以向下擴(kuò)展。

MAP_ANONYMOUS //匿名映射,映射區(qū)不與任何文件關(guān)聯(lián)。

MAP_ANON //MAP_ANONYMOUS的別稱,不再被使用。

MAP_FILE //兼容標(biāo)志,被忽略。

MAP_32BIT //將映射區(qū)放在進(jìn)程地址空間的低2GB,MAP_FIXED指定時會被忽略。當(dāng)前這個標(biāo)志只在x86-64平臺上得到支持。

MAP_POPULATE //為文件映射通過預(yù)讀的方式準(zhǔn)備好頁表。隨后對映射區(qū)的訪問不會被頁違例阻塞。

MAP_NONBLOCK //僅和MAP_POPULATE一起使用時才有意義。不執(zhí)行預(yù)讀,只為已存在于內(nèi)存中的頁面建立頁表入口。


fd:有效的文件描述詞。如果MAP_ANONYMOUS被設(shè)定,為了兼容問題,其值應(yīng)為-1。


offset:被映射對象內(nèi)容的起點。


2. 系統(tǒng)調(diào)用munmap() 

首頁 1 2 尾頁
本文糾錯】【告訴好友】【打印此文】【返回頂部
將考試網(wǎng)添加到收藏夾 | 每次上網(wǎng)自動訪問考試網(wǎng) | 復(fù)制本頁地址,傳給QQ/MSN上的好友 | 申請鏈接 | 意見留言 TOP
關(guān)于本站  網(wǎng)站聲明  廣告服務(wù)  聯(lián)系方式  站內(nèi)導(dǎo)航  考試論壇
Copyright © 2007-2013 中華考試網(wǎng)(Examw.com) All Rights Reserved
翼城县| 长岛县| 沛县| 榆中县| 东乌珠穆沁旗| 青海省| 巴塘县| 巴东县| 金华市| 宕昌县| 武山县| 抚州市| 司法| 石屏县| 顺昌县| 塘沽区| 连州市| 扎赉特旗| 宜良县| 巴彦县| 顺昌县| 安仁县| 南华县| 昌平区| 磴口县| 霍山县| 常山县| 池州市| 乌兰浩特市| 新河县| 镇远县| 稻城县| 三穗县| 茶陵县| 平谷区| 乌拉特中旗| 梁河县| 黔东| 贵溪市| 石门县| 金川县|