成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

虛擬映射和mmap()

系統 Linux
我們知道,程序是存儲在磁盤上到靜態文件;進程是對程序到一次運行過程。在進程開始運行時,進程的代碼和數據等內容必須裝入到進程用戶空間到適當區域。這些區域也就是所謂的代碼段和數據段等,而被裝入的數據和代碼等內容被稱為進程的可執行映像。

虛存映射

我們知道,程序是存儲在磁盤上到靜態文件;進程是對程序到一次運行過程。在進程開始運行時,進程的代碼和數據等內容必須裝入到進程用戶空間到適當區域。這些區域也就是所謂的代碼段和數據段等,而被裝入的數據和代碼等內容被稱為進程的可執行映像。從上面都描述中可以發現,進程在運行時并不是將程序一下子就裝入到物理內存,而只是將程序裝入到進程的用戶空間,這個裝入的過程稱為虛存映射。

一個源程序在成為可執行文件的過程中會經歷預處理、編譯、匯編和鏈接四個階段。因此,進程要成功運行不僅要在其用戶空間裝入進程映像,也要裝入該進程所用到到函數庫以及鏈接程序等。所以,一個進程到用戶空間就被分為若干個內存區域。linux使用mm_struct結構來描述一個進程到用戶地址空間,使用vm_area_struct結構來描述進程地址空間中的一個內存區域。因此,一個vm_area_struct結構可能代表進程到數據段,也可能代表鏈接程序到代碼段等。

進程的虛存映射所做的只是將磁盤上到文件映射到該進程的用戶地址空間,并沒有建立虛擬內存到物理內存的映射。當某個可執行映像映射到進程用戶空間并開始執行時,只有很少一部分虛擬頁被裝入了物理內存。在進程后續到執行過程中,如果需要訪問到數據并不在物理內存中,則產生一個缺頁中斷(其實是異常),將所需頁從交換區或磁盤中調入物理內存,這個過程即虛擬內存中到請頁機制。

進程到虛存區

那么對于一個任意的進程,我們可以通過下面到方法查看其地址空間中到內存區域。

我們先看一個簡單的測試程序:

  1. #include < stdio.h >    
  2. #include < stdlib.h >      
  3. int main()    
  4. {    
  5.  int i=1;    
  6.  char *str=NULL;    
  7.  printf("hello,world!\n");    
  8.  str=(char *)malloc(sizeof(char)*1119);    
  9.  sleep(1000);    
  10.  return 0;    
  11. }  

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

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

每一行信息依次顯示的內容為內存區域其實地址-終止地址,訪問權限,偏移量,主設備號:次設備號,inode,文件。

上面的信息不但包含了test可執行對象的各內存區域,而且還分別顯示了 /lib/ld-2.11.1.so(動態連接程序)文件和/lib/tls/i686/cmov/libc-2.11.1.so(C庫)文件的內存區域信息。

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

mmap系統調用

通過mmap系統調用可以在進程到用戶空間中創建一個新到虛存區。該系統調用到原型如下:

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

該函數可以將以打開的文件映射到進程用戶空間到一片內存區上,執行成功后,該函數返回這段映射區到首地址。用戶得到這片虛存的首地址后,就可以像訪問內存那樣訪問文件。

該系統調用的參數說明如下:

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

length:映射區以字節為單位到長度;

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

flags:這個字段比較靈活,不同到標志有不同的功能,具體如下:

MAP_SHARED:創建一個可被子進程共享的映射區;

MAP_PRIVATE:創建一個“寫實復制”的映射區;

MAP_ANONYMOUS:創建一個匿名到映射區,該虛存區與進程無關;

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

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

mmap()舉例

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

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

  1.  #include < stdio.h >    
  2.  #include < sys/mman.h >    
  3.  #include < fcntl.h >    
  4.  int main()    
  5.  {    
  6.  int i,fd;    
  7.  char *buf = NULL;    
  8.  fd = open("./test.c", O_RDONLY);    
  9.  if(fd < 0)    
  10.  {    
  11.  printf("open error\n");    
  12.  return -1;    
  13.  }    
  14.  buf = mmap(NULL, 12, PROT_READ, MAP_PRIVATE ,fd, 0);    
  15.  for(i = 0;i < 12;i++)    
  16.  {    
  17.  printf("%c",buf[i]);    
  18.  }    
  19.  printf("\n");    
  20.  return 0;    
  21. }  

try一下!

原文鏈接:http://edsionte.com/techblog/archives/2244

責任編輯:牛小雨 來源: edsionte
相關推薦

2011-04-25 17:15:39

MongodbMMAP

2023-03-01 10:37:51

2021-11-11 05:00:02

JavaMmap內存

2021-04-19 05:42:51

Mmap文件系統

2019-07-10 12:40:29

Linux虛擬地址空間物理地址空間

2021-04-30 20:20:36

HugePages大內存頁系統

2020-11-04 08:28:11

Mybatis

2009-03-24 10:12:55

ESXRDM刪除分區

2021-03-17 15:54:32

IO零拷貝方式

2021-12-03 16:20:26

鴻蒙HarmonyOS應用

2012-03-19 16:27:05

JavaHibernate

2021-04-25 09:58:48

mmapJava面試

2015-07-23 09:20:19

mmap

2022-07-11 13:09:26

mmapLinux

2023-03-06 21:29:41

mmap技術操作系統

2016-01-13 09:19:27

2009-09-23 08:56:18

Hibernate cHibernate i

2021-10-20 07:18:50

開源輕量級緩存

2009-12-23 16:16:57

Linux操作系統

2020-10-09 07:13:11

Linux系統編程mmap
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 夜夜精品浪潮av一区二区三区 | 亚洲三级av | 老妇激情毛片免费 | 日日日操 | 欧美成人免费在线视频 | 激情五月婷婷综合 | 国产一区二区在线播放 | 一级片在线播放 | 久久亚洲天堂 | 91九色在线观看 | 欧美激情一区二区三级高清视频 | 超碰97免费 | 亚洲一区二区三区高清 | 香蕉视频黄色 | 国产一区二区三区四区 | 免费成年网站 | 国产婷婷色综合av蜜臀av | 中文字幕在线免费视频 | 中文字幕在线观看精品 | 久久久久一区 | 日韩国产一区二区三区 | 狠狠狠干 | 中文字幕国产一区 | 人人玩人人添人人澡欧美 | 97精品超碰一区二区三区 | 免费看国产a | 黄色在线播放视频 | 婷婷在线网站 | 亚洲精品福利视频 | 免费h在线 | 久久天堂| 欧美精品乱码久久久久久按摩 | 久久久久网站 | 欧美在线视频网 | www.99re| 91精品成人久久 | 一区二区国产在线 | 欧美日韩久 | 欧美黄色一区 | 成人精品国产免费网站 | 久久国产精品视频观看 |