mmap函式用法及示例程式

2021-05-26 06:35:28 字數 3951 閱讀 8196

unix網路程式設計第二卷程序間通訊對mmap函式進行了說明。該函式主要用途有三個:

1、將乙個普通檔案對映到記憶體中,通常在需要對檔案進行頻繁讀寫時使用,這樣用記憶體讀寫取代i/o讀寫,以獲得較高的效能;

2、將特殊檔案進行匿名記憶體對映,可以為關聯程序提供共享記憶體空間;

3、為無關聯的程序提供共享記憶體空間,一般也是將乙個普通檔案對映到記憶體中。

標頭檔案:

#include

函式:void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);

引數start:指向欲對映的記憶體起始位址,通常設為 null,代表讓系統自動選定位址,對映成功後返回該位址。

引數length:代表將檔案中多大的部分對映到記憶體。

引數prot:對映區域的保護方式。可以為以下幾種方式的組合:

prot_exec 對映區域可被執行

prot_read 對映區域可被讀取

prot_write 對映區域可被寫入

prot_none 對映區域不能訪問

引數flags:影響對映區域的各種特性。在呼叫mmap()時必須要指定map_shared 或map_private。

map_fixed 如果引數start所指的位址無法成功建立對映時,則放棄對映,不對位址做修正。通常不鼓勵用此旗標。

map_shared對對映區域的寫入資料會複製回檔案內,而且允許其他對映該檔案的程序共享。

map_private 對對映區域的寫入操作會產生乙個對映檔案的複製,即私人的「寫入時複製」(copy on write)對此區域作的任何修改都不會寫回原來的檔案內容。

map_anonymous建立匿名對映。此時會忽略引數fd,不涉及檔案,而且對映區域無法和其他程序共享。

map_denywrite只允許對對映區域的寫入操作,其他對檔案直接寫入的操作將會被拒絕。

map_locked 將對映區域鎖定住,這表示該區域不會被置換(swap)。

引數fd:要對映到記憶體中的檔案描述符。如果使用匿名記憶體對映時,即flags中設定了map_anonymous,fd設為-1。有些系統不支援匿名記憶體對映,則可以使用fopen開啟/dev/zero檔案,然後對該檔案進行對映,可以同樣達到匿名記憶體對映的效果。

引數offset:檔案對映的偏移量,通常設定為0,代表從檔案最前方開始對應,offset必須是分頁大小的整數倍。

返回值:

若對映成功則返回對映區的記憶體起始位址,否則返回map_failed(-1),錯誤原因存於errno 中。

錯誤**:

ebadf 引數fd 不是有效的檔案描述詞

eacces 訪問許可權有誤。如果是map_private 情況下檔案必須可讀,使用map_shared則要有prot_write以及該檔案要能寫入。

einval 引數start、length 或offset有乙個不合法。

eagain 檔案被鎖住,或是有太多記憶體被鎖住。

enomem 記憶體不足。

系統呼叫mmap()用於共享記憶體的兩種方式:

(1)使用普通檔案提供的記憶體對映:

適用於任何程序之間。此時,需要開啟或建立乙個檔案,然後再呼叫mmap()

典型呼叫**如下:

fd=open(name, flag, mode); if(fd<0) ...

ptr=mmap(null, len , prot_read|prot_write, map_shared , fd , 0);

通過mmap()實現共享記憶體的通訊方式有許多特點和要注意的地方,可以參看unix網路程式設計第二卷。

(2)使用特殊檔案提供匿名記憶體對映:

適用於具有親緣關係的程序之間。由於父子程序特殊的親緣關係,在父程序中先呼叫mmap(),然後呼叫 fork()。那麼在呼叫fork()之後,子程序繼承父程序匿名對映後的位址空間,同樣也繼承mmap()返回的位址,這樣,父子程序就可以通過對映區 域進行通訊了。注意,這裡不是一般的繼承關係。一般來說,子程序單獨維護從父程序繼承下來的一些變數。而mmap()返回的位址,卻由父子程序共同維護。 對於具有親緣關係的程序實現共享記憶體最好的方式應該是採用匿名記憶體對映的方式。此時,不必指定具體的檔案,只要設定相應的標誌即可。

#

include

< unistd. h>

#include

< stdio. h>

#include

< sys/ mman. h>

#include

< fcntl. h>

#include

< stdlib. h>

//定義存放記錄的結構體

typedef

struct

record;

#define size ( 50)

#define edit_index ( 10)

int main(

void

)fclose

( fp)

;printf

("ok, write %d records to the file: records.dat ./n"

, size)

;//將第一30條記錄編號修改為300,並相應地修改其內容。

//採用傳統方式

fp =

fopen

("records.dat"

,"r+");

fseek

( fp, edit_index *

sizeof

( record)

,seek_set);

fread

(& record,

sizeof

( record)

, 1, fp)

;record. index = edit_index* 10;

sprintf

( record. text,

"no.%d"

, record. index)

;fseek

( fp, edit_index *

sizeof

( record)

,seek_set);

fwrite

(& record,

sizeof

( record)

, 1, fp)

;fclose

( fp)

;printf

("ok, edit the file of records.dat using traditional method./n");

///同樣的修改,這次使用記憶體對映方式。

//將記錄對映到記憶體中

fd =

open

("records.dat"

, o_rdwr)

;( record *

) mmap( 0, size *

sizeof

( record)

, prot_read | prot_write, map_shared, fd, 0)

;//修改資料

. index = edit_index* 10;

sprintf

. text,

"no.%d"

,. index)

;//將修改寫回對映檔案中(採用非同步寫方式)

msync(

(void

*sizeof

( record)

, ms_async)

;//釋放記憶體段

munmap(

(void

*sizeof

( record));

printf

("ok, edit the file of records.dat using mmap method./n");

//關閉檔案

close

( fd)

;return 0;

}

mmap函式用法及示例程式

unix網路程式設計第二卷程序間通訊對mmap函式進行了說明。該函式主要用途有三個 1 將乙個普通檔案對映到記憶體中,通常在需要對檔案進行頻繁讀寫時使用,這樣用記憶體讀寫取代i o讀寫,以獲得較高的效能 2 將特殊檔案進行匿名記憶體對映,可以為關聯程序提供共享記憶體空間 3 為無關聯的程序提供共享記...

mmap函式用法及示例程式

unix網路程式設計第二卷程序間通訊對mmap函式進行了說明。該函式主要用途有三個 1 將乙個普通檔案對映到記憶體中,通常在需要對檔案進行頻繁讀寫時使用,這樣用記憶體讀寫取代i o讀寫,以獲得較高的效能 2 將特殊檔案進行匿名記憶體對映,可以為關聯程序提供共享記憶體空間 3 為無關聯的程序提供共享記...

EXT JS 6示例程式 Login示例程式

1.用sencha cmd生成應用程式模版 2.建立login view元件 資料夾下,有預設的 main 資料夾,這個資料夾包含了檔案main.js,maincontroller.js,和 mainmodel.js 資料夾下建立乙個資料夾 login 在 login 資料夾下,新建兩個檔案 log...