進程間通信---共享內存

  1. 什麼是共享內存?

        共享內存就是允許兩個不相關的進程訪問同一塊物理內存。進程可將同一段共享內存連接到它們自己的地址空間中,所有進程都可以訪問共享內存中的地址。如果某一個進程向共享內存中寫入數據,所做的改動將立即影響到可以訪問同一段共享內存的其他進程。


  2. 函數接口

    (1)創建共享內存

     函數原型:int shmget(key_t key,size_t size,int shmflg)

     key :由ftok()函數返回的標識符

     size:以字節爲單位的需要共享的內存容量

     shmflg:

           IPC_CREAT:單獨使用,若共享內存不存在,創建,否則,直接打開。

           IPC_EXCL:單獨使用無意義

           IPC_CREAT | IPC_EXCL:若不存在,創建,否則返回-1.


    (2)對共享內存的訪問

     函數原型:void *shmat(int shm_id,const void* shm_addr,int shmflg)

     shm_id:是shmget函數返回的標識符

     shm_addr:指定共享內存連接到當前進程中的地址位置,通常爲NULL,表示讓系統來選擇共享內存的地址

     shm_flg:IPC_CREAT或爲0

     返回值:成功時返回指向共享內存的指針,失敗返回-1.


    (3)將共享內存從當前過程中分離

     函數原型:int shmdt(const void* shmaddr)

     shmaddr:shmat函數的返回值

     返回值:成功返回0,失敗返回-1.


    (4)控制內存共享

     函數原型:int shmctl(int shm_id,int cmd,struct shmid_ds* buf)

     shm_id: shmget函數返回的標識符

     cmd:

        IPC_STAT:把shmid_ds結構中的數據設置爲共享內存的當前關聯值,即用共享內存的當前關聯值覆蓋shmid_ds的值。

        IPC_SET:如果進程有足夠的權限,就把共享內存的當前關聯值設置爲shmid_ds結構中給出的值

        IPC_RMID:刪除共享內存段

   

“shm.h”

wKiom1eULx3gvoAvAAA_namximQ768.png

“shm.c”

wKioL1eULx2hpMWYAACNMqwD43c488.png

“test.c”

wKiom1eULx7wiORDAABq_LgH8lE530.png

運行結果:

wKioL1eULx6QAiVmAAA3tIJPfwY905.png


結果分析: 每隔一秒打印root的共享內存的情況。

     首先由父進程創建共享內存,父進程創建子進程,父子進程都關聯了共享內存,關聯的個數由0變爲2,因父進程休息時間短,取消關聯,關聯個數變爲1,最後子進程也取消關聯,關聯個數變爲0,最後將共享內存destory。。。


3.mmap函數

  mmap將一個文件或者其他對象映射進內存。mmap也可以實現共享內存。mmap函數調用使得進程之間通過映射同一個文件實現共享內存。文件被映射到進程地址空間後,進程可以像讀寫內存一樣對文件進行操作。

  函數原型:void* mmap(void* addr,size_t length,int prot,int flags,int fd,off_t offset);


  addr:映射區的開始地址,設置爲0時表示系統決定映射區的起始地址

  length:映射區的長度。長度單位爲字節

  prot:期望的內存保護標誌。取以下幾個值:

       PORT_EXEC:頁內容可以被執行   PORT_READ:頁內容可以被讀取

       PORT_WRITE:頁內容可以被寫入  PROT_NONE:頁內容不可訪問

 flag:指定映射對象的類型,映射選項與映射頁是否可以共享。

            MAP_SHARED:與其他所有映射這個對象的進程共享映射空間。

              MAP_PRIVATE:建立一個寫入時拷貝的私有映射。內存區域的寫入不會影響到原文件。

              MAP_FIXED :使用指定的映射起始地址,如果由start和len參數指定的內存區重疊於現存的映射空                                      間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。

              fd: 有效的文件描述符。返回,由一般open()函數,其值可以設置爲-1.此時需要指定flags參數爲                         MAP_ANON,表明進行的是匿名映射。

             offset:被映射對象內容的起點。

 

 返回值:成功,返回被映射區的指針;失敗,返回-1.

wKiom1eUst6SGuJfAAB_gSzEC7s509.png


wKiom1eUst6BoA12AAAj-OFdaoY229.png



  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章