System V程序間通訊 共享記憶體

2021-07-30 08:41:04 字數 3732 閱讀 7459

一、共享記憶體ipc原理

共享記憶體程序間通訊機制主要用於實現程序間大量資料的傳輸,共享記憶體是在記憶體中單獨開闢的一段記憶體空間,這段記憶體空間有自己特有的資料結構,包括訪問許可權、大小和最近訪問時間。

資料結構定義如下:

struct shmid_ds ;
兩個程序在使用此共享記憶體空間之前,需要在程序位址空間與共享記憶體空間之間建立聯絡,即將共享記憶體空間掛載到程序中。並且在使用共享記憶體進行資料的訪問時,需要對空間進行同步操作,這個可以使用訊號量機制完成。

系統對共享記憶體做了以下限制:

#define shmmin 1             /* min shared seg size (bytes) */

#define shmmni 4096 /* max num of segs system wide */

#define shmmax (ulong_max - (1ul << 24)) /* max shared seg size (bytes) */

#define shmall (ulong_max - (1ul << 24)) /* max shm system wide (pages) */

#define shmseg shmmni /* max shared segs per process */

二、共享記憶體的管理

1、建立共享記憶體

函式原型:

int shmget(key_t key, size_t size, int shm***)

函式傳入值:

key

0(ipc_private):會建立新共享記憶體物件

大於0的32位整數:視引數shm***來確定操作。通常要求此值**於ftok返回的ipc鍵值

size

大於0的整數:新建的共享記憶體大小,以位元組為單位

0:只獲取共享記憶體時指定為0

shm***

0:取共享記憶體識別符號,若不存在則函式會報錯

ipc_creat:當shm***&ipc_creat為真時,如果核心中不存在鍵值與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體,返回此共享記憶體的識別符號

ipc_creat|ipc_excl:如果核心中不存在鍵值 與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體則報錯

函式返回值:

成功:返回共享記憶體的識別符號

出錯:-1,錯誤原因存於error中

2、共享記憶體控制

函式原型:

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

函式傳入值:

shmid

共享記憶體識別符號

cmd

ipc_stat:得到共享記憶體的狀態,把共享記憶體的shmid_ds結構複製到buf中

ipc_set:改變共享記憶體的狀態,把buf所指的shmid_ds結構中的uid、gid、mode複製到共享記憶體的shmid_ds結構內

ipc_rmid:刪除這片共享記憶體

buf

共享記憶體管理結構體。具體說明參見共享記憶體核心結構定義部分

函式返回值

成功:0

出錯:-1,錯誤原因存於error中

3、對映共享記憶體物件

函式原型:

void *shmat(int shmid, const void *shmaddr, int shm***)

函式傳入值:

shmid

共享記憶體識別符號

shmaddr

指定共享記憶體出現在程序記憶體位址的什麼位置,直接指定為null讓核心自己決定乙個合適的位址位置

shm***

shm_rdonly:為唯讀模式,其他為讀寫模式

4、分離共享記憶體物件

函式原型:

int shmdt(const void *shmaddr)

函式返回值:

成功:0

出錯:-1,錯誤原因存於error中

三、使用共享記憶體進行程序間通訊的例項

1、傳送端程序

/*

*使用共享記憶體進行程序間的通訊,並運用訊號量機制實現同步

*此為資訊的傳送者

*/#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc , char* argv)

if(semctl(semid , 0 , setval , 0) == -1) //設定初始值為0

exit(exit_failure) ;

}shid = shmget((key_t)654321 , (size_t)2048 , 0600 | ipc_creat) ; //建立共享記憶體(或讀id)

if(shid == -1)

sharem = shmat(shid , null , 0) ; //掛載共享記憶體到當前程序

if(sharem == null)

while(running)

}if(strcmp(sharem , "end") == 0)

}shmdt(sharem) ; //解掛

return

0 ;}

2、接收端程序

/*

*使用共享記憶體進行程序間的通訊,並運用訊號量機制實現同步

*此為資訊的接收者

*/#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc , char* argv)

shid = shmget((key_t)654321 , (size_t)2048 , 0600 | ipc_creat) ; //建立共享記憶體(或讀id)

if(shid == -1)

sharem = shmat(shid , null , 0) ; //掛載共享記憶體到當前程序

if(sharem == null)

while(running)

printf("%s\n" , sharem) ;

}if(strcmp(sharem , "end") == 0)

}shmdt(sharem) ; //解掛

if(shmctl(shid , ipc_rmid , 0) != 0) //刪除共享記憶體

if(semctl(semid , ipc_rmid , 0) != 0) //刪除訊號量

return

0 ;}

3、我們可以檢視執行結果

傳送端:

接收端:

可以看到順利通訊(:

linuxC多程序通訊systemv 共享記憶體

共享記憶體通訊限制 舉例 獲取共享記憶體物件的id int shmget key t key,size t size,int shm 對映共享記憶體 void shmat int shmid,const void shmaddr,int shm 解除記憶體對映 int shmdt const voi...

system V 程序間通訊 訊息佇列

程序間通訊,顧名思義就是程序和程序通訊,也就是程序a和程序b可以訪問核心的同一塊空間乙個放資料,乙個取資料,那麼這兩個程序就完成通訊通訊了。訊息佇列也有管道一樣的不足 1.每個訊息的最大長度是有上限的msgmax位元組,每個訊息佇列的總位元組數是有上限的msgmnb,系統中訊息佇列的總數是有上限的m...

Ubuntu下Linux程序間通訊 共享記憶體

linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 5.共...