資料出處:
當然只有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函式 共享記憶體是一種最為高...