天天看點

linux程序通信共享存儲區流程圖,Linux程序間通信-shmget()共享記憶體(1)

Linux程序間通信--shmget()共享記憶體(一)

大多數共享記憶體的具體實作,都是把由不同程序之間共享的記憶體映射為同一段實體記憶體。 多個程序都把該實體記憶體區域映射到自己的虛拟位址空間,這些程序就都可以直接通路該共享記憶體區域,進而可以通過該區域進行通信。

linux程式通信共享存儲區流程圖,Linux程式間通信-shmget()共享記憶體(1)

共享記憶體允許兩個不相關的程序通路同一段實體記憶體, 由于資料不需要在不同的程序間複制,是以它是在兩個正在運作的程序之間傳遞資料的一種非常有效的方式,一個程序向共享記憶體區域寫入資料,共享該區域的所有程序就可以立刻看到其中的資料内容。

注意:

1.如上圖所示,共享虛拟記憶體的頁面,出現在每一個共享該頁面的程序的頁表中。但是它不需要在所有程序的虛拟記憶體中都有相同的虛拟位址。

2.共享記憶體的同步控制必須由程式員來負責。用共享記憶體來提供對大塊記憶體區域的有效通路,同時通過傳遞小道消息來同步對該記憶體的通路。

5.2 共享記憶體函數

函數原型:

#include

#include

#include

int shmget(key_t key, int size, int flag);

void* shmat(int shmid, const void *addr, int flag);

int shmdt(char *shmaddr);

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

函數描述:

shmget函數:用于開辟或指向一塊共享記憶體,傳回獲得共享記憶體區域的ID,如果不存在指定的共享區域就建立相應的區域。

keyt key: 共享記憶體的辨別符。如果是父子關系的程序間通信的話,這個辨別符用IPC_PRIVATE來代替。

如果兩個程序沒有任何關系,是以就用ftok()算出來一個辨別符(或者自己定義一個)使用了。

int size: 以位元組為機關指定需要共享的記憶體容量。

int flag: 包含9個比特的權限标志,它是這塊記憶體的模式(mode)以及權限辨別。

模式可取如下值:

IPC_CREAT 建立(如果已建立則傳回目前共享記憶體的id)

IPC_EXCL 與 IPC_CREAT結合使用,如果已建立則傳回錯誤

将“模式” 和“權限辨別”進行或運算,做為第三個參數。如:IPC_CREAT | IPC_EXCL | 0640

其中0640為權限辨別,4/2/1 分别表示讀/寫/執行3種權限,第一個0是UID,第一個6(4+2)表示擁

有者的權限,第二個4表示同組權限,第3個0表示他人的權限。

函數調用成功時傳回共享記憶體的ID,失敗時傳回-1。

注:建立共享記憶體時,shmflg參數至少需要 IPC_CREAT | 權限辨別,如果隻有IPC_CREAT 則申請的位址都是

k=0xffffffff,不能使用;

shmat函數:用來允許本程序通路一塊共享記憶體的函數。

第一次建立共享記憶體時,它不能任何程序通路,要想啟用對該共享記憶體的通路,必須将其連接配接到一個程序的位址空間中。

shmat函數就是用來完成此工作的。

int shmid : 共享記憶體的ID,即共享記憶體的辨別。

char *shmaddr: 共享記憶體連接配接到程序中的起始位址,如果shmaddr為NULL,核心會把共享記憶體映射到系統標明的地

址空間中;如果shmaddr不為NULL,核心會把共享記憶體映射到shmaddr指定的位置。

注:一般情況下我們很少需要控制共享記憶體連接配接的位址,通常都是讓系統來選擇一個位址,否則就會使應

用程式對硬體的依賴性過高。是以一般把shmaddr設為NULL。

int shmflag : 本程序對該記憶體的操作模式,可以由兩個取值:SHM_RND和SHM_RDONLY。SHM_RND為讀寫模式,

SHM_RDONLY是隻讀模式。需要注意的是,共享記憶體的讀寫權限由它的屬主、它的通路權限和當

前程序的屬主共同決定。如果當shmflg & SM_RDONLY為true時,即使該共享記憶體的通路權限允許寫操

作,它也不能被寫入。該參數通常會被設為0。

函數調用成功時,傳回共享記憶體的起始位址,失敗時傳回-1。

shmdt函數:用于函數删除本程序對這塊記憶體的使用。

shmdt()與shmat()相反,是用來禁止本程序通路一塊共享記憶體的函數。

char *shmaddr 是那塊共享記憶體的起始位址。

函數調用成功時傳回0,失敗時傳回-1。

shmctl函數: 控制對這塊共享記憶體的使用。

int shmid: 共享記憶體的ID,即共享記憶體辨別。

int cmd : 控制指令,表示要采取的動作,可取值如下:

IPC_STAT 得到共享記憶體的狀态:把shmid_ds結構中的資料設定為共享記憶體的目前關聯值

IPC_SET 改變共享記憶體的狀态:把共享記憶體的目前關聯值設定為shmid_ds結構中給出的值

IPC_RMID 删除共享記憶體段

shmid_ds結構至少包含以下成員:

struct shmid_ds {

uid_t shm_perm.uid;

uid_t shm_perm.gid;

uid_t shm_perm.mode;

}

struct shmid_ds *buf: 一個結構體指針。IPC_STAT的時候,取得的狀态放在這個結構體中。

如果要改變共享記憶體的狀态,用這個結構體指定。

函數調用成功時傳回0,失敗時傳回-1。