Linux記憶體對映

2021-05-21 11:36:43 字數 2391 閱讀 2465

使用記憶體對映處理大檔案很方便,在windows系統中,實現了這樣的藉口。在linux中我們也可以通過mmap函式來實現。以下內容完全參考自

如有冒犯,請諒解

mmap函式實現把乙個檔案對映到乙個記憶體區域,從而我們可以像讀寫記憶體一樣讀寫檔案,他比單純呼叫read/write也要快上許多。在某些時候我們可以把記憶體的內容拷貝到乙個檔案中實現記憶體備份,當然,也可以把檔案的內容對映到記憶體來恢復某些服務。另外,mmap實現共享記憶體也是其主要應用之一,mmap系統呼叫使得程序之間通過對映同乙個普通檔案實現共享記憶體。

關於mmap的內容請看《unix環境高階程式設計》12章。在這裡,說一下使用mmap函式時可能遇到的問題:

//下面的**把檔案1.ls中的內容通過mmap函式寫入2.ls中,忽略出錯處理

int fd=open("1.ls",o_rdonly);

int fd2=open("2.ls",o_creat|o_rdwr|o_trunc,s_irusr|s_iwusr);//必須設定讀寫許可權,若只有寫許可權,會產生sigsegv訊號

//mmap進行檔案對映時必須先讀取檔案`

struct stat st;

fstat(fd,&st);

lseek(fd2,st.st_size-1,seek_set);

write(fd2,"",1); //必須的,如果不設定,當寫入資料的時候會遇到檔案結束符,產生sigbus訊號

void *_src=mmap(null,st.st_size,prot_read,map_shared, fd,0);

void *_des=mmap(null,st.st_size,prot_write,map_shared,fd2,0);

close(fd); //關閉檔案後 依然可修改檔案內容

close(fd2);

memcpy(_des,_src,st.st_size);

總結一下,可能產生的問題如下:

1.進行檔案對映的描述符必須擁有讀許可權,否則會產生sigsegv訊號

2.把記憶體內容寫入對映檔案時,必須確保被寫檔案當前位置到檔案結尾的長度不小於所寫內容長度,否則產生sigbus訊號

3.關閉檔案描述符並不能保證檔案內容不被修改

4.munmap並不能使對映的內容寫回磁碟

也許會奇怪為什麼有匯流排錯誤,其實我也鬱悶了好久,才弄明白.lseek了乙個空洞 但是並引起i/o操作

也就是說如果lseek之後沒有發生i/o操作時,lseek只是把偏移量給改了一下並沒有在磁碟上分配儲存區

而你的檔案是新建的 儲存的空間長度為0 lseek之後還是為0.把mmap到系統的線性位址空間,然後進行複製的話就會出錯.

一種方法如上,lseek後加個write。還有乙個辦法就是ftruncate(fdout, statbuf.st_size) == 0了

#include #include #include #include #include #include #include #include #include int main(int argc,char *argv) 

pagesize = sysconf(_sc_pagesize);

printf("pagesize: %ld/n", (long)pagesize);

if((fdin = open(argv[1],o_rdonly)) == -1)

if((fdout = open(argv[2],o_rdwr | o_creat | o_trunc,0644)) == -1)

assert(fstat(fdin,&statbuf) == 0);

printf("filein size = %ld/n",statbuf.st_size);

assert(ftruncate(fdout, statbuf.st_size) == 0

&& fstat(fdout, &statbuf) == 0);

printf("fileout size = %ld/n",statbuf.st_size);

src = mmap(0,statbuf.st_size,prot_read,map_shared,fdin,0);

if( src == map_failed )

dst = mmap(0,statbuf.st_size,prot_read | prot_write,map_shared,fdout,0);

if( dst == map_failed )

memcpy(dst,src,statbuf.st_size);

close(fdin);

close(fdout);

return 0;

}

Linux記憶體對映

本文討論的linux版本是linux 2.6.26.5,體系結構是smdk2410,採用arm s3c2410。在該版本中虛擬位址是32位位址,採用四級頁表結構,依次是 pgd pud pmd pte offset page shift pmd shift pud shift pgdir shift...

linux記憶體對映

記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有 頁框,管理區 高階記憶體,低端記憶體 高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。一 頁框 頁框為物理記憶體分配的基...

linux記憶體對映

記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有 頁框,管理區 高階記憶體,低端記憶體 高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。一 頁框 頁框為物理記憶體分配的基...