共享存儲區(Share Memory)是Linux系統中通訊速度最高的通訊機制。該機制中共享內存空間和進程的虛地址空間知足多對多的關係。即一個共享內存空間能夠映射多個進程的虛地址空間,一個進程的虛地址空間又能夠鏈接多個共享存儲區。當進程間預利用共享存儲區通訊時,先要在主存中創建一個共享存儲區,而後將它附接到本身的虛地址空間。該機制只爲進程提供了用於實現通訊的共享存儲區和對共享存儲區進行操做的手段,然而並未提供對該區進行互斥訪問及進程同步的措施。linux
shmget(key ,size ,flag)數組
功能:得到一個內部標識爲shmid的共享存儲區。數據結構
語法:int shmget = int shmget(key_t key ,int size ,int flag);函數
參數說明:操作系統
key 共享存儲區關鍵字,可由用戶指定。若使用IPC_PRIVATE則其值由系統產生。3d
size 存儲區大小(字節數)。若存儲區定義爲字符型,則大小爲定義的字符個數;若定義爲整型,大小能夠用sizeof(int)加以定義code
flag 用戶設置的標誌或訪問方式,如0666|IPC_CREAT,表示任意進程皆可讀可寫blog
操做容許權 | 八進制數 | 操做容許權 | 八進制數 |
---|---|---|---|
用戶可讀 | 0400 | 小組可寫 | 0020 |
用戶可寫 | 0200 | 其它可讀 | 0004 |
小組可讀 | 0040 | 其它可寫 | 0002 |
字符型共享內存:進程
shmat(int shmid ,char shmadddr ,int msgflg ,ulong raddr);內存
數值型共享內存:
shmat(int shmid ,int shmadddr ,int msgflg ,ulong raddr);
語法格式:
字符型共享內存:
viraddr = (char *) shmat (shmid ,shmaddr ,shmflag);
viraddr = (int *) shmat (shmid ,shmaddr ,shmflag);
參數說明:
shmid共享存儲區的描述符,可由shmget()的返回值獲得。
shmaddr用戶提供的共享存儲區附接的虛地址。
shmflag規定存儲區的操做權限。如,SHM_RND則表示操做系統在必要時捨去地址;SHM_RDONLY則表示只容許讀,shmflag爲0表示可讀可寫。
shmdt(viraddr)
參數說明:
viraddr系統調用shmat()所返回的虛地址。
返回值:
函數被正確調用則返回0,錯誤返回-1
shmctl(int shmid ,int cmd ,struct shmid_ds * buf);
功能:對共享內存進行操做控制
參數說明:
shmid共享存儲區的描述符,可由shmget()的返回值獲得。
buf用戶級數據結構地址,可爲0。
cmd規定的操做類型
操做代碼 | 含義 |
---|---|
IPC_STAT | 返回指定shmid數據結構的狀態信息,放置於*buf中,必須有讀取容許權 |
IPC_SET | 設置指定shmid的有效用戶和操做存取權 |
IPC_RMID | 刪除指定shmid以及與它相關的共享存儲區的數據結構 |
SHM_LOCK | 在內存中鎖定指定的共享存儲區,必須是root才能執行 |
shmctl(shmid ,IPC_RMID ,0); //撤銷共享內存區
send:
receive:
send
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> /*共享內存 share memory 實現的進程通訊*/ main() { int shmid; char *viraddr; char buffer[BUFSIZ]; shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); while(1) { puts("Enter some text:"); fgets(buffer,BUFSIZ,stdin);/*從標準輸入設備讀入一行字符串,stdin是標準輸入,C標準庫裏面的一 個全局變量*/ strcat(viraddr,buffer); /*字符串追加函數*/ if(strncmp(buffer,"end",3)==0)/*比較兩個字符串數組*/ break; } shmdt(viraddr); exit(0); }
receive
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> main() { int shmid; char *viraddr; shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); printf("Your message is :\n%s",viraddr); shmdt(viraddr); /*斷開鏈接*/ shmctl(shmid,IPC_RMID,0); /*撤銷共享內存*/ exit(0); }
運行結果
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/shm.h> /* 父進程與子進程間的通訊,子進程寫信息到共享內存中,父進程讀取該信息 BUFSIZ爲全局量定義在<stdlib.h>,8192 使用exit(0)和wait(0)進行同步*/ main() { int chld,shmid; char *viraddr; char buffer[BUFSIZ]; shmid=shmget(IPC_PRIVATE,BUFSIZ,0666|IPC_CREAT); viraddr=(char*)shmat(shmid,0,0); while((chld=fork())==-1); if(chld==0) { /*子進程塊*/ while(1) { puts("Enter some text:"); /*寫信息到共享內存*/ fgets(buffer,BUFSIZ,stdin); /*用戶輸入信息*/ strcat(viraddr,buffer); /*附接到進程的虛擬空間*/ if(strncmp(buffer,"end",3)==0) break; /*輸入end結束*/ } exit(0); } else { /*父進程塊*/ wait(0); printf("Your message is:\n%s",viraddr); shmdt(viraddr); /*斷開共享內存*/ shmctl(shmid,IPC_RMID,0); /*釋放共享內存*/ exit(0); } }
運行結果