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

2021-06-06 02:57:25 字數 3687 閱讀 2654

資料出處:

當然只有mmap是可以的,不過由於各種不同的系統的架構不一樣,後來又經過整合,所以我們現在的linux有多種記憶體共享方案,下面在介紹一種非常常用的系統v記憶體方案。

本人首先再在上次的基礎之上介紹乙個**

(國防科大的仁兄)

本人在自己理解的基礎上一步一步去深入

#include

#include

#include

#include

#include

int main()

else printf("created shared-memory: %d\n",shmid);

system("ipcs -m");

if((shmadd=shmat(shmid,0,0))<(char *)0)

else printf("attached shared-memory\n");

system("ipcs -m");

if((shmdt(shmadd))<0) //禁止本程序再使用該共享記憶體區

else printf("deleted shared-memory\n");

system("ipcs -m");

if(shmctl(shmid,ipc_rmid,&shmbuf)<0)

system("ipcs -m");

return 0;

}shmget

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

key: 識別符號的規則

size:共享儲存段的位元組數

flag:讀寫的許可權

返回值:成功返回共享儲存的id,失敗返回-1

shmat

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

shmid:共享儲存的id

flag:如前所述,一般為0

shmdt

int shmdt(void *addr);

addr:共享儲存段的位址,以前呼叫shmat時的返回值

shmdt將使相關shmid_ds結構中的shm_nattch計數器值減1

shmctl

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

shmid:共享儲存段的id

cmd:一些命令,有:ipc_stat,ipc_rmid,shm_lock,shm_unlock

程式說明:

結合我一些函式的說明,這個程式應該就很容易懂了,另外需要補充的是,檢視共享記憶體段的命令式:ipcs -m,刪除共享記憶體段的命令是:ipcrm -m shmid,請注意,共享記憶體不會隨著程式結束而自動消除,要麼呼叫shmctl刪除,要麼自己用手敲命令去刪除,否則永遠留在系統中

另看ipc_write.c

#include

#include

#include

#include

typedef struct

people;

int main(int argc,char **argv)

p_map=(people*)shmat(shm_id,null,0);

temp_char='a';

for(i=0;i<10;i++)

if(shmdt(p_map)<0)

perror("detach error");

return 0;

}ipc_read.c

#include

#include

#include

#include

typedef struct

people;

int main(int argc,char **argv)

if(shmdt(p_map)<0)

perror("shmdt error");

if(shmctl(shm_id,ipc_rmid,&shmbuf)<0)

perror("shmctl error");

return 0;

}ipc_write.c實現向共享記憶體裡面寫,ipc_read.c實現從共享記憶體裡面讀

不過在ipc_write.c的shmget的第乙個引數是ipc_private,所以分配的key的值是

由系統產生的,並且沒有任何標誌獨特性的key_t的值。那麼ipc_read.c是如何知道shm_id的呢?我這個是自己手工查ipcs -m得來的,那麼程式設計中如何實現呢?

1.建立具有非常鮮明特徵,獨特的key值

2.通過訊號量,訊息佇列或者管道(fifo)傳輸這個shm_id

shm_id也有人用,不過稍微麻煩一點,下面介紹用第一種方法

shm_ftok_write.c

#include

#include

#include

#include

typedef struct

people;

int main(int argc,char **argv)

p_map=(people*)shmat(shm_id,null,0);

temp_char='a';

for(i=0;i<10;i++)

if(shmdt(p_map)==-1)

perror("detach error");

return 0;

}ipc_ftok_read.c

#include

#include

#include

#include

typedef struct

people;

int main(int argc,char **argv)

p_map=(people*)shmat(shm_id,null,0);

p_map=(people*)shmat(393216,null,0);

for(i=0;i<10;i++)

if(shmdt(p_map)==-1)

perror("detach error");

return 0;

}這裡用的是獨特鮮明的key值

執行程式之前,先建立"/dev/shm/myshm1"檔案

最好是寫成自己的執行檔案的目錄,如"/home/nsl/myprogram/ipc_ftok_write"這樣就不會存在檔案不存在的情況了

ftok

key_t ftok( char * fname, int id )

frame:檔案的全路徑,要求檔案存在且程序可訪問

id:第幾個共享記憶體

返回值:返回key值

註明:系統v共享記憶體與mmap相比,就是系統v共享記憶體從來不把資料真正寫到磁碟檔案中去,而mmap機制在munmap的時候將資料寫到磁碟檔案

發現原來系統v共享記憶體也需要檔案的支撐

當然,共享記憶體沒有這麼容易,還有大量的同步要做

再補充點共享記憶體的派系知識:

unix程序間通訊方式包括:管道、fifo、訊號。

system v程序間通訊方式包括:system v訊息佇列、system v訊號燈、system v共享記憶體。

posix程序間通訊包括:posix訊息佇列、posix訊號燈、posix共享記憶體。

個人覺得,mmap是posix共享記憶體

shmget是system v共享記憶體

程序間通訊 共享記憶體 shmget

介紹這一部分主要從它的幾個函式入手 概念 共享記憶體是在物理記憶體上開闢一塊區域,這段被多個程序對映到自己程序的虛擬位址空間上,這些程序就可以直接訪問該共享記憶體區域,從而通過該區域實現各程序間的通訊。共享記憶體是程序間最快的一種通訊方式,乙個程序向共享記憶體上面寫資料,共享這塊記憶體的所有程序都可...

程序間通訊 共享記憶體

下面是自己寫的乙個簡單的共享記憶體的程序間通訊的例子。共享記憶體是用於程序間大量資料共享的一種方法。include include include include include include int main if buf1 shmat shmid,0,0 void 1 strcpy buf1,...

程序間通訊 共享記憶體

共享記憶體是被多個程序共享的一部分物理記憶體。共享記憶體是程序間共享資料的一種最快的方式,乙個程序向共享記憶體區域寫入資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。共享記憶體實現分兩個步驟 建立共享記憶體,使用shmget函式 對映共享記憶體,使用shmat函式 共享記憶體是一種最為高...