衆所周知,進程間通訊有三種方式,信號量、消息隊列和共享內存。不過信號量我的感受不像通訊,其實就是一個鎖的東西。數組
共享內存,無非就是在內存段開闢一段小內存,返回地址,供以多個進程來使用,有的進程來這裏存數據,有的進程來取數據。函數
要使用一塊共享內存,進程必須首先分配它。隨後須要訪問這個共享內存塊的每個進程都必須將這個共享內存綁定到本身的地址空間中。當完成通訊以後,全部進程都將脫離共享內存,而且由一個進程釋放該共享內存塊。全部共享內存塊的大小都必須是系統頁面大小的整數倍。(4K*n)
ui
1.API:spa
共享內存函數由shmget、shmat、shmdt、shmctl四個函數組成。按步驟以下:
指針
1shmget: int shmget(key_t key, size_t size, int shmflg) 獲得一個共享內存標識符或建立一個共享內存對象並返回共享內存標識符
code
key
|
0(IPC_PRIVATE):會創建新共享內存對象
|
大於0的32位整數:視參數shmflg來肯定操做。一般要求此值來源於ftok返回的IPC鍵值
|
|
size
|
大於0的整數:新建的共享內存大小,以字節爲單位
|
0:只獲取共享內存時指定爲0
|
|
shmflg
|
0:取共享內存標識符,若不存在則函數會報錯
|
IPC_CREAT:當shmflg&IPC_CREAT爲真時,若是內核中不存在鍵值與key相等的共享內存,則新建一個共享內存;若是存在這樣的共享內存,返回此共享內存的標識符
|
|
IPC_CREAT|IPC_EXCL:若是內核中不存在鍵值與key相等的共享內存,則新建一個消息隊列;若是存在這樣的共享內存則報錯
|
2shmat :把共享內存區對象映射到調用進程的地址空間htm
void *shmat(int shmid, const void *shmaddr, int shmflg)
對象
shmid
|
共享內存標識符
|
shmaddr
|
指定共享內存出如今進程內存地址的什麼位置,直接指定爲NULL讓內核本身決定一個合適的地址位置
|
shmflg
|
SHM_RDONLY:爲只讀模式,其餘爲讀寫模式
|
3 管控共享內存 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
|
共享內存管理結構體。具體說明參見共享內存內核結構定義部分
|
4 斷開共享內存鏈接 int shmdt(const void *shmaddr) //shmaddr:鏈接的共享內存的起始地址進程
2.小例子和解釋:
發送方.c進程申請一段共享內存,把一個結構體放入裏面,接收方.c進程讀取這段內存,讀出內容。
SENDER.C
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
struct personinfo{ //要存放的結構體
char name[10];
int number;
float scores;
};
typedef struct personinfo * player; //聲明結構體指針
int main(void){
int shmid;
shmid=shmget(IPC_PRIVATE,4096,0666); //申請共享內存,大小4K,有rwxrwxrwx權限
if(shmid==-1) // shmid就是共享內存的標識
exit(1);
printf("shmid is %d\n",shmid);
player wade; //建立一個指針對象
wade=shmat(shmid,NULL,0);// shmat(shmid,NULL,0)就是把shmid標識的共享內存的地址鏈接到本進程,這裏直接給到結構體指針,就是把結構體指針指向這段內存;
strcpy(wade->name,"dwyane_wade");
wade->number=3;
wade->scores=20.13;
if(shmdt(wade)<0)//解除連接
exit(1);
return 0;
}
RSVER.C
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> struct personinfo{ char name[10]; int number; float scores; }; typedef struct personinfo * player; int main(int argc,char *argv[]){ int shmid; shmid=atoi(argv[1]);// 從輸入端把SENDER.C獲得的shmid輸入 player lee; if((lee=shmat(shmid,NULL,0))==NULL) //把指針指向內存這裏 exit(1); printf("name %s\n",lee->name); //讀取數據 printf("number %d\n",lee->number); printf("scores %f\n",lee->scores); }
運行結果應該是 dwyane_wade\n 3\n 20.129999\n