共享內存

效率: 採用共享內存通訊的一個顯而易見的好處是效率高,由於進程能夠直接讀寫內存,而不須要任何數據的拷貝。對於像管道和消息隊列等通訊方式,則須要在內核和用戶空間進行四次的數據拷貝,而共享內存則只拷貝兩次數據[1]: 一次從輸入文件到共享內存區,另外一次從共享內存區到輸出文件。實際上,進程之間在共享內存時,並不老是讀寫少許數據後就解除映射,有新的通訊時,再從新建 立共享內存區域。而是保持共享區域,直到通訊完畢爲止,這樣,數據內容一直保存在共享內存中,並無寫回文件。共享內存中的內容每每是在解除映射時才寫回 文件的。所以,採用共享內存的通訊方式效率是很是高的。函數

共享內存沒有任何的同步與互斥機制,因此要使用信號量來實現對共享內存的存取的同步ui

shmget函數spa

shmget函數建立一個新的共享內存區,或者訪問一個已存在的共享內存區。操作系統

#include <sys/shm.h>.net

int  shmget (key_t key,  size_t size, int oflag) ;unix

返回值是一個稱爲共享內存區標識符的整數,其餘三個shmXXX函數就用它來指代這個內存區。指針

參數key既能夠是ftok的返回值,也能夠是IPC_PRIVATE。系統創建IPC通信 ( 消息隊列、 信號量和 共享內存) 時必須指定一個ID值。一般狀況下,該id值經過ftok函數獲得,由內核變成標識符,要想讓兩個進程看到同一個信號集,只需設置key值不變就能夠。blog

參數size是指定內存區的大小。(若訪問已存在的內存區,則size應爲0),它的值通常爲一頁大小的整數倍(未到一頁,操做系統向上對齊到一頁,可是用戶實際能使用只有本身所申請的大小)。隊列

參數oflag是讀寫權限值的組合。建立一個新的共享內存,將shmflg 設置了IPC_CREAT標誌後,共享內存存在就打開。而IPC_CREAT | IPC_EXCL則能夠建立一個新的,惟一的共享內存,若是共享內存已存在,返回一個錯誤。通常咱們會還或(‘|’)上一個文件權限進程

當實際操做爲建立一個新的共享內存區時,該內存區被初始化爲size字節的0。

shmat函數

由shmget函數建立或打開一個共享內存區後,經過調用shmat把它附接到調用進程的地址空間。

#include <sys/shm.h>

void* shmat (int shmid,  const void* shmaddr,  int flag) ;

參數shmid是由shmget返回的標識符。

shmat的返回值是所指定的共享內存區在調用進程內的起始地址。(通常把參數shmaddr置爲NULL,讓系統替調用者選擇地址)

參數flag能夠指定SHM_RDONLY值,它限定只讀訪問。(默承認同時讀寫)一般爲0.

shmdt函數

當一個進程完成某個共享內存區的使用時,它能夠調用shmdt斷接這個內存區。

#include <sys/shm.h>

int  shmdt (const void* shmaddr) ;

參數addr是之前調用shmat時的返回值

當一個進程終止時,它當前附接着的全部共享內存區都自動斷接掉。

注意,本函數只是斷開關聯,並不刪除所指定的共享內存區。刪除工做經過以IPC_RMID命令調用shmctl完成。(XSI IPC都是隨內核持續的)

shmctl函數

shmctl提供了對一個共享內存區的多種操做。

#include <sys/shm.h>

int  shmctl (int shmid,  int cmd, struct shmid_ds* buff) ;

參數cmd:

IPC_RMID 從系統中刪除該共享存儲段。由於每一個共享存儲段有一個鏈接計數器,因此除非使用該段的最後一個進程終止或與該段脫接,不然不會實際上刪除該存儲段。但無論此段是否仍在使用,該段標識符當即被刪除,因此不能再用shmat與該段鏈接

 

(1)第一個參數,shm_id是shmget函數返回的共享內存標識符。
(2)第二個參數,cmd是要採起的操做,它能夠取下面的三個值 :    
IPC_STAT:把shmid_ds結構中的數據設置爲共享內存的當前關聯值,即用共享內存的當前關聯值覆蓋shmid_ds的值。    
 
IPC_SET:若是進程有足夠的權限,就把共享內存的當前關聯值設置爲shmid_ds結構中給出的值    
 
IPC_RMID:刪除共享內存段
 
(3)第三個參數,buf是一個結構指針,它指向共享內存模式和訪問權限的結構。 shmid_ds結構至少包括如下成員 

struct shmid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};

轉自:https://blog.csdn.net/ctthuangcheng/article/details/9271431

實踐經驗:unix內核並不像格式化磁盤同樣格式化共享內存,因此用戶必須人爲的把大共享內存劃分爲單個的小記錄塊。

常見應用模型:

1.  1-1模型

相關文章
相關標籤/搜索