linux 進程間通信——內存共享映射mmap和munmap


IPC三種通信機制是指:信號量、共享內存、消息隊列,
 
信號量:通過操作系統中的PV操作來實現;
共享內存:申請一塊內存,進程A往共享內存中寫,其他的進程就可以通過讀出共享內存中的內容來獲取進程A所傳送的信息;
消息隊列:創建一個消息隊列,進程A往隊列里面寫,那么進程B通過讀隊列中的容來獲取進程A傳送的信息。
 
 

  mmap可以把磁盤文件的一部分直接映射到內存,這樣文件中的位置直接就有對應的內存地址,對文件的讀寫可以直接用指針來操做而不需要read/write函數。

#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length);

 

   

  如果addr參數為NULL,內核會自己在進程地址空間中選擇合適的地址建立映射。如果addr不是NULL,則給內核一個提示,應該從什么地址開始映射,內核會選擇addr之上的某個合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到len參數是需要映射的那一部分文件的長度。off參數是從文件的什么位置開始映射,必須是頁大小的整數倍(在32位體系統結構上通常是4K)。filedes是代表該文件的描述符。 
   
prot參數有四種取值: 
  1)PROT_EXEC 表示映射的這一段可執行,例如映射共享庫 
  2)PROT_READ 表示映射的這一段可讀 
  3)PROT_WRITE 表示映射的這一段可寫 
  4) PROT_NONE 表示映射的這一段不可訪問 
    
flag參數有很多種取值,這里只講兩種常用的,其它取值可查看mmap(2)

  • MAP_SHARED 多個進程對同一個文件的映射是共享的,一個進程對映射的內存做了修改,另一個進程也會看到這種變化。
  • MAP_PRIVATE 多個進程對同一個文件的映射不是共享的,一個進程對映射的內存做了修改,另一個進程並不會看到這種變化,也不會真的寫到文件中去。

* 如果mmap成功則返回映射首地址,如果出錯則返回常數MAP_FAILED。當進程終止時,該進程的映射內存會自動解除,也可以調用munmap解除映射。munmap成功返回0,出錯返回-1。 

 

 

/* 運行前准備 */
book@ubuntu:~$ vi hello
book@ubuntu:~$ cat hello
helloworld
book@ubuntu:~$ od -tx1 -tc hello
0000000 68 65 6c 6c 6f 77 6f 72 6c 64 0a
        h  e  l  l  o  w  o  r  l  d  \n
0000013

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>

int main(void)
{
    int fd, *p, len;
    fd = open("hello",O_RDWR);
    if(fd < 0)
    {
        perror("open");
        exit(1);
    }
    //獲取文件長度
    len = lseek(fd, 0, SEEK_END);
    //建立映射
    p = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if(p == MAP_FAILED)
    {//如果失敗,記住這種檢測方式
        perror("mmap");
        exit(1);
    }
    //即使關閉文件也不會釋放映射
    close(fd);
    //由於是共享映射,所以映射源也會被修改
    p[0] = 0x30313233;

    munmap(p, len);

    return 0;
}


/* 運行后結果(小端存儲的原因) */
book@ubuntu:~$ cat hello
3210oworld
book@ubuntu:~$ od -tx1 -tc hello
0000000 33 32 31 30 6f 77 6f 72 6c 64 0a
        3  2  1  0  o  w  o  r  l  d  \n
0000013
利用內存映射的特性,也可以用於進程間的通信,但是要注意的是: 1、用於進程間通信時,一般設計成結構體,來傳輸通信的數據 2、進程間通信的文件,應該設計成臨時文件(即創建文件,使用文件,刪除文件) 3、 當報總線錯誤時,優先查看共享文件是否有存儲空間 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM