程序間通訊IPC之 共享記憶體

2021-09-07 06:38:51 字數 3719 閱讀 6369

每個程序各自有不同的使用者位址空間,任何乙個進 程的全域性變數在另乙個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝 區,程序1把資料從使用者空間拷到核心緩衝區,程序2再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊(ipc,interprocess communication)

如下圖所示:

程序間通訊共七種方式:

第一類:傳統的unix通訊機制:

# 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。

# 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。

# 訊號 ( sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。

第二類:system v ipc: 

# 訊號量( semophore ) : 訊號量是乙個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。

# 訊息佇列( message queue ) : 訊息佇列是由訊息的鍊錶,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。

# 共享記憶體( shared memory ) :共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由乙個程序建立,但多個程序都可以訪問。共享記憶體是最快的 ipc 方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號兩,配合使用,來實現程序間的同步和通訊。

第三類:bsd 套接字:

# 套接字( socket ) : 套解字也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同及其間的程序通訊。

共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同乙個物理記憶體區域的指標。當乙個程序改變了這塊位址中的內容的時候,其它程序都會察覺到這個更改。程序可以直接讀取共享記憶體,不需要拷貝資料。由於多個程序共享同一塊記憶體區域,必然需要某種同步機制,互斥鎖和訊號量都可以。

步驟:共享記憶體的使用,主要有以下幾個api:ftok()、shmget()、shmat()、shmdt()及shmctl()

①建立/開啟共享記憶體

int shmget(key_t key,int size,int shmflag); 例:

key = ftok(".", 'm');

shmid = shmget(key,1024,0666|ipc_creat|ipc_excl);

引數說明:

key:是這塊共享記憶體的識別符號。如果是父子關係的程序間通訊的話,這個識別符號用ipc_private來代替。如果兩個程序沒有任何關係,所以就用ftok()算出來乙個識別符號(或者自己定義乙個)使用了。

產生key的方法:key_t ftok(const char *pathname, int proj_id);

#define ipckey 0x344378

size:申請記憶體的大小

shmflag:  這塊記憶體的模式(mode)以及許可權標識(0666等)。 

申請的記憶體裡面為空,即全為0

②對映共享記憶體,即把指定的共享記憶體對映到程序的位址空間用於訪問

void *shmat( int shmid , char *shmaddr , int shmflag );

例:void *p;

p=shmat(shmid,null,0);

引數說明:

shmid:是那塊共享記憶體的id。

shmaddr:共享記憶體對映的起始位址,一般不指定即null

shmflag:本程序對該記憶體的操作模式。如果是shm_rdonly的話,就是唯讀模式。0是讀寫模式

③撤銷共享記憶體對映,刪除本程序對這塊記憶體的使用

int shmdt(const void* shmaddr);

例:shmdt(p);

引數說明:

shmaddr:共享記憶體的起始位址。

返回值:成功時返回0。失敗時返回-1。

④刪除共享記憶體物件

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

例:shmctl(shmid, ipc_rmid, null);(刪除共享記憶體)

引數說明:

shmid:共享記憶體的id。

cmd:控制命令,可取值如下:

ipc_stat        得到共享記憶體的狀態

ipc_set         改變共享記憶體的狀態

ipc_rmid        刪除共享記憶體

buf:乙個結構體指標。用以儲存/設定屬性。ipc_stat的時候,取得的狀態放在這個結構體中。如果要改變共享記憶體的狀態,用這個結構體指定。

返回值:成功時返回0。失敗時返回-1。

無**無真相

功能說明:兩個程序通過共享記憶體乙個寫乙個讀並列印資料

/*name:writer.c

*function:寫端程序向共享記憶體寫資料

* */

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define n 64

typedef struct 

shm;

void handler(int signo)

int main()

signal(sigusr1, handler);//註冊乙個訊號處理函式

if ((shmid = shmget(key, sizeof(shm), 0666|ipc_creat|ipc_excl)) 

else//出錯

}else//成功 

while ( 1 )

shmdt(p);

shmctl(shmid, ipc_rmid, null);//刪除共享記憶體

return 0;}

/*name:reader.c

*function:讀端程序從共享記憶體中讀資料

* */

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define n 64

typedef struct 

shm;

void handler(int signo)

int main()

signal(sigusr1, handler);//註冊乙個訊號處理函式

if ((shmid = shmget(key, sizeof(shm), 0666|ipc_creat|ipc_excl)) 

else//出錯

}else//成功

程序間通訊IPC 共享記憶體

共享記憶體 共享記憶體 就是開闢一段物理記憶體使多個程序共享 是程序間最高效的傳輸方式 共享記憶體必須結合其他方式來實現程序間的同步 程式設計步驟 1 開闢一段共享記憶體 int shmget key t key,size t size,int shm key t key ftok a stat s...

IPC程序間通訊(共享記憶體)

共享記憶體區是最快的ipc形式。一旦這樣的記憶體對映到共享它的程序的位址空間,這些程序間資料傳遞不再涉及到核心,換句話說是程序不再通過執行進入核心的系統呼叫來傳遞彼此的資料。用管道或者訊息佇列傳遞資料,核心為每個ipc物件維護乙個資料結構 用共享記憶體傳遞資料 struct shmid ds inc...

程序間通訊(IPC) 共享記憶體

共享記憶體是被多個程序共享的一部分物理記憶體。共享記憶體是程序間共享資料的一種最快的方法,乙個程序向共享記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。把物理記憶體按要求申請出來給多個程序使用,共享記憶體訪問起來比較快,用起來比較簡單,不需要一些特別的函式。共享記憶體實現...