Linux下進程間通訊--共享內存:最快的進程間通訊方式

共享內存:函數

1、概念:ui

        共享內存能夠說是最有用的進程間通訊方式,也是最快的IPC形式。兩個不一樣進程A、B共享內存的意思是,同一塊物理內存被映射到進程A、B各自的進程地址空間。spa

進程A能夠即時看到進程B對共享內存中數據的更新,反之亦然。因爲多個進程共享同一塊內存區域,必然須要某種同步機制,互斥鎖和信號量均可以。.net

採用共享內存通訊的一個顯而易見的好處是效率高,由於進程能夠直接讀寫內存,而不須要任何數據的拷貝。指針

對於像管道和消息隊列等通訊方式,則須要在內核和用戶空間進行四次的數據拷貝,code

而共享內存則只拷貝兩次數據[1]: blog

1.一次從輸入文件到共享內存區,接口

2.另外一次從共享內存區到輸出文件。隊列

實際上,進程之間在共享內存時,並不老是讀寫少許數據後就解除映射,有新的通訊時,再從新建 立共享內存區域。而是保持共享區域,直到通訊完畢爲止,這樣,數據內容一直保存在共享內進程

存中,並無寫回文件。共享內存中的內容每每是在解除映射時才寫回 文件的。所以,採用共享內存的通訊方式效率是很是高的。

2、相關函數:

與信號量同樣,在Linux中也提供了一組函數接口用於使用共享內存,並且使用共享共存的接口還與信號量的很是類似,並且比使用信號量的接口來得簡單。它們聲明在頭文件 sys/shm.h中。

一、shmget函數
該函數用來建立共享內存,它的原型爲:
int shmget(key_t key, size_t size, int shmflg);  
1.第一個參數,與信號量的semget函數同樣,程序須要提供一個參數key(非0整數),它有效地爲共享內存段命名。

    shmget函數成功時返回一個與key相關的共享內存標識符(非負整數),用於後續的共享內存函數。調用失敗返回-1.

    不相關的進程能夠經過該函數的返回值訪問同一共享內存,它表明程序可能要使用的某個資源,程序對全部共享內存的訪問都是間接的,程序先經過調用shmget函數並提供一個鍵,再由

系統生 成一個相應的共享內存標識符(shmget函數的返回值),只有shmget函數才直接使用信號量鍵,全部其餘的信號量函數使用由semget函數返回的信號量標識符。

2.第二個參數,size以字節爲單位指定須要共享的內存容量

3.第三個參數,shmflg是權限標誌,它的做用與open函數的mode參數同樣,若是要想在key標識的共享內存不存在時,建立它的話,能夠與IPC_CREAT作或操做。

共享內存的權限標誌與文件的讀寫權限同樣,舉例來講,0644,它表示容許一個進程建立的共享內存被內存建立者所擁有的進程向共享內存讀取和寫入數據,同時其餘用戶建立的進程只能讀取共

享內存。

二、shmat函數
第一次建立完共享內存時,它還不能被任何進程訪問,shmat函數的做用就是用來啓動對該共享內存的訪問,並把共享內存鏈接到當前進程的地址空間。它的原型以下:
void *shmat(int shm_id, const void *shm_addr, int shmflg); 
第一個參數,shm_id是由shmget函數返回的共享內存標識。

第二個參數,shm_addr指定共享內存鏈接到當前進程中的地址位置,一般爲空,表示讓系統來選擇共享內存的地址。

第三個參數,shm_flg是一組標誌位,一般爲0。

調用成功時返回一個指向共享內存第一個字節的指針,若是調用失敗返回-1.

三、shmdt函數
該函數用於將共享內存從當前進程中分離。注意,將共享內存分離並非刪除它,只是使該共享內存對當前進程再也不可用。它的原型以下:
int shmdt(const void *shmaddr);  
參數shmaddr是shmat函數返回的地址指針,調用成功時返回0,失敗時返回-1.

四、shmctl函數
與信號量的semctl函數同樣,用來控制共享內存,它的原型以下:
int shmctl(int shm_id, int command, struct shmid_ds *buf); 
第一個參數,shm_id是shmget函數返回的共享內存標識符

第二個參數,command是要採起的操做,它能夠取下面的三個值 :
    IPC_STAT:把shmid_ds結構中的數據設置爲共享內存的當前關聯值,即用共享內存的當前關聯值覆蓋shmid_ds的值。
    IPC_SET:若是進程有足夠的權限,就把共享內存的當前關聯值設置爲shmid_ds結構中給出的值
    IPC_RMID:刪除共享內存段

第三個參數,buf是一個結構指針,它指向共享內存模式和訪問權限的結構。
shmid_ds結構至少包括如下成員:
struct shmid_ds  
{  
    uid_t shm_perm.uid;  
    uid_t shm_perm.gid;  
    mode_t shm_perm.mode;  
};  
3、實例:

關於共享內存的實例見下面博客,已經很好了,我也就不在班門弄斧了:

賜教!
相關文章
相關標籤/搜索