什么是虛擬映射和mmap()

這篇文章給大家介紹什么是虛擬映射和mmap(),內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比彭州網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式彭州網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋彭州地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。

虛存映射

我們知道,程序是存儲(chǔ)在磁盤上到靜態(tài)文件;進(jìn)程是對(duì)程序到一次運(yùn)行過程。在進(jìn)程開始運(yùn)行時(shí),進(jìn)程的代碼和數(shù)據(jù)等內(nèi)容必須裝入到進(jìn)程用戶空間到適當(dāng)區(qū)域。這些區(qū)域也就是所謂的代碼段和數(shù)據(jù)段等,而被裝入的數(shù)據(jù)和代碼等內(nèi)容被稱為進(jìn)程的可執(zhí)行映像。從上面都描述中可以發(fā)現(xiàn),進(jìn)程在運(yùn)行時(shí)并不是將程序一下子就裝入到物理內(nèi)存,而只是將程序裝入到進(jìn)程的用戶空間,這個(gè)裝入的過程稱為虛存映射。

一個(gè)源程序在成為可執(zhí)行文件的過程中會(huì)經(jīng)歷預(yù)處理、編譯、匯編和鏈接四個(gè)階段。因此,進(jìn)程要成功運(yùn)行不僅要在其用戶空間裝入進(jìn)程映像,也要裝入該進(jìn)程所用到到函數(shù)庫(kù)以及鏈接程序等。所以,一個(gè)進(jìn)程到用戶空間就被分為若干個(gè)內(nèi)存區(qū)域。linux使用mm_struct結(jié)構(gòu)來描述一個(gè)進(jìn)程到用戶地址空間,使用vm_area_struct結(jié)構(gòu)來描述進(jìn)程地址空間中的一個(gè)內(nèi)存區(qū)域。因此,一個(gè)vm_area_struct結(jié)構(gòu)可能代表進(jìn)程到數(shù)據(jù)段,也可能代表鏈接程序到代碼段等。

進(jìn)程的虛存映射所做的只是將磁盤上到文件映射到該進(jìn)程的用戶地址空間,并沒有建立虛擬內(nèi)存到物理內(nèi)存的映射。當(dāng)某個(gè)可執(zhí)行映像映射到進(jìn)程用戶空間并開始執(zhí)行時(shí),只有很少一部分虛擬頁(yè)被裝入了物理內(nèi)存。在進(jìn)程后續(xù)到執(zhí)行過程中,如果需要訪問到數(shù)據(jù)并不在物理內(nèi)存中,則產(chǎn)生一個(gè)缺頁(yè)中斷(其實(shí)是異常),將所需頁(yè)從交換區(qū)或磁盤中調(diào)入物理內(nèi)存,這個(gè)過程即虛擬內(nèi)存中到請(qǐng)頁(yè)機(jī)制。

進(jìn)程到虛存區(qū)

那么對(duì)于一個(gè)任意的進(jìn)程,我們可以通過下面到方法查看其地址空間中到內(nèi)存區(qū)域。

我們先看一個(gè)簡(jiǎn)單的測(cè)試程序:

#include < stdio.h >    #include < stdlib.h >      int main()    {     int i=1;     char *str=NULL;     printf("hello,world!\n");     str=(char *)malloc(sizeof(char)*1119);     sleep(1000);     return 0;    }

這個(gè)程序中使用到了malloc函數(shù),因此str變量存儲(chǔ)于堆中。我們通過打印/proc/3530/maps文件,即可看到該進(jìn)程的內(nèi)存空間劃分。其中3530是該進(jìn)程的id。

edsionte@edsionte-desktop:~$ cat /proc/3530/maps    0014a000-00165000 r-xp 00000000 08:07 398276 /lib/ld-2.11.1.so    00165000-00166000 r--p 0001a000 08:07 398276 /lib/ld-2.11.1.so    00166000-00167000 rw-p 0001b000 08:07 398276 /lib/ld-2.11.1.so    001d8000-0032b000 r-xp 00000000 08:07 421931 /lib/tls/i686/cmov/libc-2.11.1.so    0032b000-0032c000 ---p 00153000 08:07 421931 /lib/tls/i686/cmov/libc-2.11.1.so    0032c000-0032e000 r--p 00153000 08:07 421931 /lib/tls/i686/cmov/libc-2.11.1.so    0032e000-0032f000 rw-p 00155000 08:07 421931 /lib/tls/i686/cmov/libc-2.11.1.so    0032f000-00332000 rw-p 00000000 00:00 0    00441000-00442000 r-xp 00000000 00:00 0 [vdso]    08048000-08049000 r-xp 00000000 08:09 326401 /home/edsionte/test    08049000-0804a000 r--p 00000000 08:09 326401 /home/edsionte/test    0804a000-0804b000 rw-p 00001000 08:09 326401 /home/edsionte/test    08958000-08979000 rw-p 00000000 00:00 0 [heap]    b78ce000-b78cf000 rw-p 00000000 00:00 0    b78dd000-b78e0000 rw-p 00000000 00:00 0    bfa6a000-bfa7f000 rw-p 00000000 00:00 0 [stack]

每一行信息依次顯示的內(nèi)容為內(nèi)存區(qū)域其實(shí)地址-終止地址,訪問權(quán)限,偏移量,主設(shè)備號(hào):次設(shè)備號(hào),inode,文件。

上面的信息不但包含了test可執(zhí)行對(duì)象的各內(nèi)存區(qū)域,而且還分別顯示了 /lib/ld-2.11.1.so(動(dòng)態(tài)連接程序)文件和/lib/tls/i686/cmov/libc-2.11.1.so(C庫(kù))文件的內(nèi)存區(qū)域信息。

我們從某個(gè)內(nèi)存區(qū)域的訪問權(quán)限上可以大致判斷該區(qū)域的類型。各個(gè)屬性符號(hào)的意義為:r-read,w-write,x-execute,s-shared,p-private。因此,r-x一般代表程序的代碼段,即可讀,可執(zhí)行。rw-可能代表數(shù)據(jù)段,BSS段和堆棧段等,即可讀,可寫。堆棧段從行信息的文件名就可以區(qū)分;如果某行信息的文件名為空,那么可能是BSS段。另外,上述test進(jìn)程共享了內(nèi)核動(dòng)態(tài)庫(kù),所以在00441000-00442000行處文件名顯示為vdso(Virtual Dynamic Shared Object)。

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

通過mmap系統(tǒng)調(diào)用可以在進(jìn)程到用戶空間中創(chuàng)建一個(gè)新到虛存區(qū)。該系統(tǒng)調(diào)用到原型如下:

#include    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

該函數(shù)可以將以打開的文件映射到進(jìn)程用戶空間到一片內(nèi)存區(qū)上,執(zhí)行成功后,該函數(shù)返回這段映射區(qū)到首地址。用戶得到這片虛存的首地址后,就可以像訪問內(nèi)存那樣訪問文件。

該系統(tǒng)調(diào)用的參數(shù)說明如下:

addr:映射到用戶地址空間到起始地址;

length:映射區(qū)以字節(jié)為單位到長(zhǎng)度;

prot:對(duì)映射區(qū)到訪問模式。包括PROT_EXEC(可執(zhí)行),PROT_READ (可讀),PROT_WRITE(可寫),PROT_NONE(文件不可訪問)。這個(gè)訪問模式不能超過所映射文件到打開模式。比如被映射的文件打開模式為只讀,那么此處到訪問模式不能是可讀寫的。

flags:這個(gè)字段比較靈活,不同到標(biāo)志有不同的功能,具體如下:

MAP_SHARED:創(chuàng)建一個(gè)可被子進(jìn)程共享的映射區(qū);

MAP_PRIVATE:創(chuàng)建一個(gè)“寫實(shí)復(fù)制”的映射區(qū);

MAP_ANONYMOUS:創(chuàng)建一個(gè)匿名到映射區(qū),該虛存區(qū)與進(jìn)程無關(guān);

fd:所要映射到進(jìn)程用戶空間的文件描述符,該文件必須為以打開的文件;

offset:文件的起始映射偏移量;

mmap()舉例

在該程序中,首先以只讀方式打開文件test.c,再通過該文件返回到文件描述符和mmap函數(shù)將test.c文件映射到當(dāng)前進(jìn)程到用戶地址空間中。成功執(zhí)行mmap函數(shù)后,buf被賦值為所映射的虛存區(qū)的首地址。注意,mmap函數(shù)返回的是void型指針,而buf是char型指針。將mmap返回值賦值給buf變量時(shí),自動(dòng)將void*轉(zhuǎn)化為char*型。

***,就像平常我們使用一個(gè)char型指針變量那樣,依次打印出buf中到數(shù)據(jù)。

 #include < stdio.h >     #include < sys/mman.h >     #include < fcntl.h >     int main()     {     int i,fd;     char *buf = NULL;     fd = open("./test.c", O_RDONLY);     if(fd < 0)     {     printf("open error\n");     return -1;     }     buf = mmap(NULL, 12, PROT_READ, MAP_PRIVATE ,fd, 0);     for(i = 0;i < 12;i++)     {     printf("%c",buf[i]);     }     printf("\n");     return 0;    }

關(guān)于什么是虛擬映射和mmap()就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

本文題目:什么是虛擬映射和mmap()
當(dāng)前URL:http://bm7419.com/article34/phodpe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、建站公司網(wǎng)站策劃、網(wǎng)站營(yíng)銷網(wǎng)站收錄、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名