天天看點

mmap VS munmap mkstemp

功能描述: 

mmap将一個檔案或者其它對象映射進記憶體。檔案被映射到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間将會清零。munmap執行相反的操作,删除特定位址區域的對象映射。 

于檔案的映射,在mmap和munmap執行過程的任何時刻,被映射檔案的st_atime可能被更新。如果st_atime字段在前述的情況下沒有得到

更新,首次對映射區的第一個頁索引時會更新該字段的值。用PROT_WRITE 和 MAP_SHARED标志建立起來的檔案映射,其st_ctime

和 st_mtime

在對映射區寫入之後,但在msync()通過MS_SYNC 和 MS_ASYNC兩個标志調用之前會被更新。

用法:  

#include 

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

    int fd, off_t offset);

int munmap(void *start, size_t length); 

參數:   

start:映射區的開始位址。

length:映射區的長度。

prot:期望的記憶體保護标志,不能與檔案的打開模式沖突。是以下的某個值,可以通過or運算合理地組合在一起

PROT_EXEC //頁内容可以被執行

PROT_READ  //頁内容可以被讀取

PROT_WRITE //頁可以被寫入

PROT_NONE  //頁不可通路

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

MAP_FIXED //使用指定的映射起始位址,如果由start和len參數指定的記憶體區重疊于現存的映射空間,重疊部分将會被丢棄。如果指定的起始位址不可用,操作将會失敗。并且起始位址必須落在頁的邊界上。

MAP_SHARED //與其它所有映射這個對象的程序共享映射空間。對共享區的寫入,相當于輸出到檔案。直到msync()或者munmap()被調用,檔案實際上不會被更新。

MAP_PRIVATE //建立一個寫入時拷貝的私有映射。記憶體區域的寫入不會影響到原檔案。這個标志和以上标志是互斥的,隻能使用其中一個。

MAP_DENYWRITE //這個标志被忽略。

MAP_EXECUTABLE //同上

MAP_NORESERVE //不要為這個映射保留交換空間。當交換空間被保留,對映射區修改的可能會得到保證。當交換空間不被保留,同時記憶體不足,對映射區的修改會引起段違例信号。

MAP_LOCKED //鎖定映射區的頁面,進而防止頁面被交換出記憶體。

MAP_GROWSDOWN //用于堆棧,告訴核心VM系統,映射區可以向下擴充。

MAP_ANONYMOUS //匿名映射,映射區不與任何檔案關聯。

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

MAP_FILE //相容标志,被忽略。

MAP_32BIT //将映射區放在程序位址空間的低2GB,MAP_FIXED指定時會被忽略。目前這個标志隻在x86-64平台上得到支援。

MAP_POPULATE //為檔案映射通過預讀的方式準備好頁表。随後對映射區的通路不會被頁違例阻塞。

MAP_NONBLOCK //僅和MAP_POPULATE一起使用時才有意義。不執行預讀,隻為已存在于記憶體中的頁面建立頁表入口。

fd:有效的檔案描述詞。如果MAP_ANONYMOUS被設定,為了相容問題,其值應為-1。

offset:被映射對象内容的起點。

傳回說明:   

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

EACCES:通路出錯

EAGAIN:檔案已被鎖定,或者太多的記憶體已被鎖定

EBADF:fd不是有效的檔案描述詞

EINVAL:一個或者多個參數無效

ENFILE:已達到系統對打開檔案的限制

ENODEV:指定檔案所在的檔案系統不支援記憶體映射

ENOMEM:記憶體不足,或者程序已超出最大記憶體映射數量

EPERM:權能不足,操作不允許

ETXTBSY:已寫的方式打開檔案,同時指定MAP_DENYWRITE标志

SIGSEGV:試着向隻讀區寫入

SIGBUS:試着通路不屬于程序的記憶體區

int mkstemp(char *template);

        mkstemp函數在系統中以唯一的檔案名建立一個檔案并打開,而且隻有目前使用者才能通路這個臨時檔案,并進行讀、寫操作。mkstemp函數隻有一個參 數,這個參數是個以“XXXXXX”結尾的非空字元串。mkstemp函數會用随機産生的字元串替換“XXXXXX”,保證了檔案名的唯一性。         函數傳回一個檔案描述符,如果執行失敗傳回-1。         在glibc 2.0.6 以及更早的glibc庫中這個檔案的通路權限是0666,glibc 2.0.7以後的庫這個檔案的通路權限是0600。         臨時檔案使用完成後應及時删除,否則臨時檔案目錄會塞滿垃圾。由于mkstemp函數建立的臨時檔案不能自動删除,是以執行完mkstemp函數後要調用 unlink函數,unlink函數删除檔案的目錄入口,但臨時檔案還可以通過檔案描述符進行通路,直到最後一個打開的程序關閉檔案操作符,或者程式退出 後臨時檔案被自動徹底地删除。         下面是一個使用mkstemp的例子: int main(void) {         int fd;         char temp_file[]="tmp_XXXXXX";                 if((fd=mkstemp(temp_file))==-1)         {                 printf("Creat temp file faile./n");                 exit(1);         }                  unlink(temp_file);                 //ADD YOUR CODE;                 close(fd); }

繼續閱讀