int shmget(key_t key, size_t size, int flag);
key: 標識符的規則
size:***享存儲段的字節數
flag:讀寫的權限
返回值:成功返回***享存儲的id,失敗返回-1
key_t key
-----------------------------------------------
key標識***享內存的鍵值: 0/IPC_PRIVATE。 當key的取值為IPC_PRIVATE,則函數shmget()將創建壹塊新的***享內存;如果key的取值為0,而參數shmflg中設置了IPC_PRIVATE這個標誌,則同樣將創建壹塊新的***享內存。
在IPC(InterProcess Communication)的通信模式下,不管是使用消息隊列還是***享內存,甚至是信號量,每個IPC的對象(object)都有唯壹的名字,稱為“鍵”(key)。通過“鍵”,進程能夠識別所用的對象。“鍵”與IPC對象的關系就如同文件名稱之於文件,通過文件名,進程能夠讀寫文件內的數據,甚至多個進程能夠***用壹個文件。而在IPC的通訊模式下,通過“鍵”的使用也使得壹個IPC對象能為多個進程所***用。
Linux系統中的所有表示System V中IPC對象的數據結構都包括壹個ipc_perm結構,其中包含有IPC對象的鍵值,該鍵用於查找System V中IPC對象的引用標識符。如果不使用“鍵”,進程將無法存取IPC對象,因為IPC對象並不存在於進程本身使用的內存中。
通常,都希望自己的程序能和其他的程序預先約定壹個唯壹的鍵值,但實際上並不是總可能的成行的,因為自己的程序無法為壹塊***享內存選擇壹個鍵值。因此,在此把key設為IPC_PRIVATE,這樣,操作系統將忽略鍵,建立壹個新的***享內存,指定壹個鍵值,然後返回這塊***享內存IPC標識符ID。而將這個新的***享內存的標識符ID告訴其他進程可以在建立***享內存後通過派生子進程,或寫入文件或管道來實現。
int size(單位字節Byte)
-----------------------------------------------
size是要建立***享內存的長度。所有的內存分配操作都是以頁為單位的。所以如果壹段進程只申請壹塊只有壹個字節的內存,內存也會分配整整壹頁(在i386機器中壹頁的缺省大小PACE_SIZE=4096字節)這樣,新創建的***享內存的大小實際上是從size這個參數調整而來的頁面大小。即如果size為1至4096,則實際申請到的***享內存大小為4K(壹頁);4097到8192,則實際申請到的***享內存大小為8K(兩頁),依此類推。
int shmflg
-----------------------------------------------
shmflg主要和壹些標誌有關。其中有效的包括IPC_CREAT和IPC_EXCL,它們的功能與open()的O_CREAT和O_EXCL相當。
IPC_CREAT 如果***享內存不存在,則創建壹個***享內存,否則打開操作。
IPC_EXCL 只有在***享內存不存在的時候,新的***享內存才建立,否則就產生錯誤。
如果單獨使用IPC_CREAT,shmget()函數要麽返回壹個已經存在的***享內存的操作符,要麽返回壹個新建的***享內存的標識符。如果將IPC_CREAT和IPC_EXCL標誌壹起使用,shmget()將返回壹個新建的***享內存的標識符;如果該***享內存已存在,或者返回-1。IPC_EXEL標誌本身並沒有太大的意義,但是和IPC_CREAT標誌壹起使用可以用來保證所得的對象是新建的,而不是打開已有的對象。對於用戶的讀取和寫入許可指定SHM_R和SHM_W,(SHM_R>3)和(SHM_W>3)是壹組讀取和寫入許可,而(SHM_R>6)和(SHM_W>6)是全局讀取和寫入許可。
需要註意的是,使用參數要加上 | 0666 作為校驗,在有些Linux系統中,如果不加此校驗,則不能順利獲取***享空間的值(如Ubuntu)。此外,有兩個常用參數,壹般要同時出現,他們是:S_IRUSH | S_IWUSR 。由於這兩個參數非常常用,程序員壹般做這樣的操作
#define PERM S_IRUSR | S_IWUSR | IPC_CREAT
這樣壹來,第三個參數就可以直接用PERM來表示了!
返回值
-----------------------------------------------
成功返回***享內存的標識符;不成功返回-1,errno儲存錯誤原因。
EINVAL 參數size小於SHMMIN或大於SHMMAX。
EEXIST 預建立key所致的***享內存,但已經存在。
EIDRM 參數key所致的***享內存已經刪除。
ENOSPC 超過了系統允許建立的***享內存的最大值(SHMALL )。
ENOENT 參數key所指的***享內存不存在,參數shmflg也未設IPC_CREAT位。
EACCES 沒有權限。
ENOMEM 核心內存不足。