在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ 內(nèi)存映射
命名管道
消息隊列
進(jìn)程創(chuàng)建與終止
信號量
進(jìn)程組,會話和作業(yè)控制
共享內(nèi)存
進(jìn)程間通信簡介
子進(jìn)程監(jiān)視
其他進(jìn)程
覆蓋進(jìn)程映像
進(jìn)程信息
進(jìn)程映像
內(nèi)存映射
相關(guān)系統(tǒng)調(diào)用(System V)
進(jìn)程資源
System V & Posix
信號
進(jìn)程間通信教程
管道

內(nèi)存映射

mmap()系統(tǒng)調(diào)用在調(diào)用進(jìn)程的虛擬地址空間中提供映射,將文件或設(shè)備映射到內(nèi)存中。 下面是兩種類型 -

文件映射或文件支持的映射 - 此映射將進(jìn)程的虛擬內(nèi)存區(qū)域映射到文件。 這意味著讀取或?qū)懭脒@些內(nèi)存區(qū)域會導(dǎo)致文件被讀取或?qū)懭?。這是默認(rèn)的映射類型。

匿名映射 - 此映射映射進(jìn)程的虛擬內(nèi)存區(qū)域,不受任何文件的支持。 內(nèi)容被初始化為零。 這種映射類似于動態(tài)內(nèi)存分配(malloc()),在某些malloc()實現(xiàn)中用于某些分配。

一個進(jìn)程映射中的內(nèi)存可以與其他進(jìn)程中的映射共享。 這可以通過兩種方式完成 -

  • 當(dāng)兩個進(jìn)程映射文件的同一個區(qū)域時,它們共享相同的物理內(nèi)存頁面。
  • 如果創(chuàng)建了一個子進(jìn)程,它將繼承父進(jìn)程的映射,并且這些映射引用與父進(jìn)程相同的物理內(nèi)存頁面。 在子進(jìn)程中的任何數(shù)據(jù)更改后,將為子進(jìn)程創(chuàng)建不同的頁面。

當(dāng)兩個或多個進(jìn)程共享相同的頁面時,每個進(jìn)程可以根據(jù)映射類型查看其他進(jìn)程所做的頁面內(nèi)容更改。 映射類型可以是私有的也可以是共享的 -

  • 私有映射(MAP_PRIVATE) - 對此映射的內(nèi)容所做的修改對其他進(jìn)程是不可見的,并且映射不會傳遞到底層文件。
  • 共享映射(MAP_SHARED) - 對此映射內(nèi)容的修改對其他進(jìn)程可見,并將映射傳送到底層文件。
#include <sys/mman.h>

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

上述系統(tǒng)調(diào)用返回成功映射的起始地址,或者返回MAP_FAILED出錯。

虛擬地址addr可以是用戶指定的,也可以是內(nèi)核生成的(將addr作為NULL傳遞)。 指示的字段長度需要以字節(jié)為單位的映射大小。 字段prot表示內(nèi)存保護(hù)值,例如PROT_NONE,PROT_READ,PROT_WRITEPROT_EXEC分別表示不可訪問,讀取,寫入或執(zhí)行的區(qū)域。 該值可以是單個(PROT_NONE),也可以是三個標(biāo)志中的任何一個(最后3個)。 字段標(biāo)志指示映射類型或MAP_PRIVATEMAP_SHARED。 字段'fd'表示標(biāo)識要映射的文件的文件描述符,字段'offset'表示文件的起始點,如果需要映射整個文件,offset應(yīng)該是零。

#include <sys/mman.h>

int munmap(void *addr, size_t length);

上述系統(tǒng)調(diào)用在成功時返回0,錯誤時返回-1。

系統(tǒng)調(diào)用munmap,執(zhí)行已映射內(nèi)存區(qū)域的映射。 字段addr指示映射的起始地址,length指示要被映射的映射的大小(以字節(jié)為單位)。 通常,映射和解映射將針對整個映射區(qū)域。 如果這必須有所不同,那么它應(yīng)該被縮小或分成兩部分。 如果addr沒有任何映射,這個調(diào)用將不起作用,調(diào)用返回0(成功)。

讓我們考慮一個例子 -

第1步 - 寫入文件如下所示的字母數(shù)字字符 -

0 1 2 25 26 27 38 59 60 61
A B C Z 0 1 2 x y z

第2步 - 使用mmap()系統(tǒng)調(diào)用將文件內(nèi)容映射到內(nèi)存中。 這將映射到內(nèi)存后返回起始地址。

第3步 - 使用數(shù)組表示法訪問文件內(nèi)容(也可以使用指針表示法訪問),因為不會讀取昂貴的read()系統(tǒng)調(diào)用。 使用內(nèi)存映射,避免在用戶空間,內(nèi)核空間緩沖區(qū)和緩沖區(qū)緩存之間進(jìn)行多次復(fù)制。
第4步 - 重復(fù)讀取文件內(nèi)容,直到用戶輸入“-1”(表示訪問結(jié)束)。
第5步 - 執(zhí)行清理活動,即取消映射映射的內(nèi)存區(qū)域(munmap()),關(guān)閉文件并刪除文件。

/* Filename: mmap_test.c */
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
void write_mmap_sample_data();

int main() {
   struct stat mmapstat;
   char *data;
   int minbyteindex;
   int maxbyteindex;
   int offset;
   int fd;
   int unmapstatus;
   write_mmap_sample_data();
   if (stat("MMAP_DATA.txt", &mmapstat) == -1) {
      perror("stat failure");
      return 1;
   }

   if ((fd = open("MMAP_DATA.txt", O_RDONLY)) == -1) {
      perror("open failure");
      return 1;
   }
   data = mmap((caddr_t)0, mmapstat.st_size, PROT_READ, MAP_SHARED, fd, 0);

   if (data == (caddr_t)(-1)) {
      perror("mmap failure");
      return 1;
   }
   minbyteindex = 0;
   maxbyteindex = mmapstat.st_size - 1;

   do {
      printf("Enter -1 to quit or ");
      printf("enter a number between %d and %d: ", minbyteindex, maxbyteindex);
      scanf("%d",&offset);
      if ( (offset >= 0) && (offset <= maxbyteindex) )
      printf("Received char at %d is %c\n", offset, data[offset]);
      else if (offset != -1)
      printf("Received invalid index %d\n", offset);
   } while (offset != -1);
   unmapstatus = munmap(data, mmapstat.st_size);

   if (unmapstatus == -1) {
      perror("munmap failure");
      return 1;
   }
   close(fd);
   system("rm -f MMAP_DATA.txt");
   return 0;
}

void write_mmap_sample_data() {
   int fd;
   char ch;
   struct stat textfilestat;
   fd = open("MMAP_DATA.txt", O_CREAT|O_TRUNC|O_WRONLY, 0666);
   if (fd == -1) {
      perror("File open error ");
      return;
   }
   // Write A to Z
   ch = 'A';

   while (ch <= 'Z') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   // Write 0 to 9
   ch = '0';

   while (ch <= '9') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   // Write a to z
   ch = 'a';

   while (ch <= 'z') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   close(fd);
   return;
}

執(zhí)行上面示例代碼,得到以下結(jié)果 -

Enter -1 to quit or enter a number between 0 and 61: 3 
Received char at 3 is D 
Enter -1 to quit or enter a number between 0 and 61: 28
Received char at 28 is 2 
Enter -1 to quit or enter a number between 0 and 61: 38 
Received char at 38 is c 
Enter -1 to quit or enter a number between 0 and 61: 59 
Received char at 59 is x 
Enter -1 to quit or enter a number between 0 and 61: 65 
Received invalid index 65 
Enter -1 to quit or enter a number between 0 and 61: -99 
Received invalid index -99 
Enter -1 to quit or enter a number between 0 and 61: -1

上一篇:其他進(jìn)程下一篇:命名管道