一、什麼是共享記憶體
顧名思義。共享記憶體就是同意兩個不相關的程序訪問同乙個邏輯記憶體。共享記憶體是在兩個正在執行的程序之間共享和傳遞資料的一種很有效的方式。不同程序之間共享的記憶體通常安排為同一段物理記憶體。
程序能夠將同一段共享記憶體連線到它們自己的位址空間中,全部程序都能夠訪問共享記憶體中的位址。就好像它們是由用c語言函式malloc分配的記憶體一樣。
而假設某個程序向共享記憶體寫入資料,所做的修改將馬上影響到能夠訪問同一段共享記憶體的不論什麼其它程序。
特別提醒:共享記憶體並未提供同步機制。也就是說,在第乙個程序結束對共享記憶體的寫操作之前。並無自己主動機制能夠阻止第二個程序開始對它進行讀取。所以我們通常須要用其它的機制來同步對共享記憶體的訪問。比如前面說到的訊號量。有關訊號量的很多其它內容。能夠查閱我的還有一篇文章:linux程序間通訊——使用訊號量
二、共享記憶體的使得
與訊號量一樣。在linux中也提供了一組函式介面用於使用共享記憶體,並且使用共享共存的介面還與訊號量的很相似。並且比使用訊號量的介面來得簡單。它們宣告在標頭檔案 sys/shm.h中。
1、shmget函式
該函式用來建立共享記憶體。它的原型為:
int shmget(key_t key, size_t size, int shm***);
第乙個引數
,與訊號量的semget函式一樣,程式須要提供乙個引數key(非0整數)。它有效地為共享記憶體段命名。shmget函式成功時返回乙個與key相關的共享記憶體識別符號(非負整數),用於興許的共享記憶體函式。
呼叫失敗返回-1.
不相關的程序能夠通過該函式的返回值訪問同一共享記憶體。它代表程式可能要使用的某個資源,程式對全部共享記憶體的訪問都是間接的,程式先通過呼叫shmget函式並提供乙個鍵,再由系統生成乙個對應的共享記憶體識別符號(shmget函式的返回值),僅僅有shmget函式才直接使用訊號量鍵。全部其它的訊號量函式使用由semget函式返回的訊號量識別符號。
第二個引數,size以位元組為單位指定須要共享的記憶體容量
第三個引數。shm***是許可權標誌,它的作用與open函式的mode引數一樣,假設要想在key標識的共享記憶體不存在時,建立它的話,能夠與ipc_creat做或操作。
共享記憶體的許可權標誌與檔案的讀寫許可權一樣,舉例來說。0644,它表示同意乙個程序建立的共享記憶體被記憶體建立者所擁有的程序向共享記憶體讀取和寫入資料,同一時候其它使用者建立的程序僅僅能讀取共享記憶體。
2、shmat函式
第一次建立完共享記憶體時,它還不能被不論什麼程序訪問,shmat函式的作用就是用來啟動對該共享記憶體的訪問,並把共享記憶體連線到當前程序的位址空間。
它的原型例如以下:
void *shmat(int shm_id, const void *shm_addr, int shm***);
第乙個引數,shm_id是由shmget函式返回的共享記憶體標識。
第二個引數,shm_addr指定共享記憶體連線到當前程序中的位址位置,通常為空,表示讓系統來選擇共享記憶體的位址。
第三個引數,shm_***是一組標誌位,通常為0。
呼叫成功時返回乙個指向共享記憶體第乙個位元組的指標,假設呼叫失敗返回-1.
3、shmdt函式
該函式用於將共享記憶體從當前程序中分離。注意,將共享記憶體分離並非刪除它。僅僅是使該共享記憶體對當前程序不再可用。
它的原型例如以下:
int shmdt(const void *shmaddr);
引數shmaddr是shmat函式返回的位址指標,呼叫成功時返回0,失敗時返回-1.
4、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
;
測試用例源**:
#include#include#include#include#include #include #include #include #define perm s_irusr|s_iwusr
int main(int argc,char **ar**)
if((shmid=shmget(ipc_private,1024,perm))==-1)
if(fork())
else
return 1;
}
編譯後輸出:
client get 12345
五、使用共享記憶體的優缺點
1、長處:我們能夠看到使用共享記憶體進行程序間的通訊真的是很方便,並且函式的介面也簡單,資料的共享還使程序間的資料不用傳送,而是直接訪問記憶體。也加快了程式的效率。同一時候,它也不像匿名管道那樣要求通訊的程序有一定的父子關係。
2、缺點:共享記憶體沒有提供同步的機制,這使得我們在使用共享記憶體進行程序間通訊時,往往要借助其它的手段來進行程序間的同步工作。
linux程序間通訊,使用共享記憶體方式
閒來沒事給想要學習程序間使用共享記憶體通訊的例子,共享記憶體的效率比訊息佇列 訊號量都要高?為什麼呢?1 共享記憶體是執行在使用者空間的,由應用程式控制。2 訊息佇列和訊號量都是把資料從乙個程序使用者空間複製到核心空間,然後再由核心控制項複製到另外乙個程序的使用者空間。include include...
Linux程序間通訊 使用匿名管道
在前面,介紹了一種程序間的通訊方式 使用訊號,我們建立通知事件,並通過它引起響應,但傳遞的資訊只是乙個訊號值。這裡將介紹另一種程序間通訊的方式 匿名管道,通過它程序間可以交換更多有用的資料。一 什麼是管道 如果你使用過linux的命令,那麼對於管道這個名詞你一定不會感覺到陌生,因為我們通常通過符號 ...
Ubuntu下Linux程序間通訊 共享記憶體
linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 5.共...