我會用幾篇博客總結一下在Linux中進程之間通訊的幾種方法,我會把這個開頭的摘要部分在這個系列的每篇博客中都打出來html
進程之間通訊的方式服務器
進程間通訊(五)—信號傳送門:http://www.cnblogs.com/lenomirei/p/5656449.htmlsocket
進程間通訊(三)—信號量傳送門:http://www.cnblogs.com/lenomirei/p/5649792.html函數
進程間通訊(二)—消息隊列傳送門:http://www.cnblogs.com/lenomirei/p/5642575.html測試
進程間通訊(一)—管道傳送門:http://www.cnblogs.com/lenomirei/p/5636339.htmlspa
這篇主要記錄的是共享存儲區的相關操做,說是共享存儲區,其實就是共享內存,進程擁有的能互相通訊存儲區也就有內存了吧操作系統
爲何用共享存儲區進行通訊?由於快!管道是文件,操做慢,消息隊列建立操做都有消耗因此慢,共享內存是要建立好兩個進程均可以直接對這塊內存進行操做,互相都是可見的。指針
爲何用共享存儲區編寫程序?由於接口簡單!操做絕對比消息隊列簡單好多。code
雖然感受很簡單的事情,可是仍是要建立開闢一下,否則每一個進程都用本身的地址空間映射到不一樣的物理地址,哪怕虛擬地址是同樣的,也是各自獨立的,互相不可見,聲明瞭這個共享存儲區以後,才能夠往這個公共的區域映射(這樣纔有用不是麼)。server
調用這個函數就能夠開闢一個共享存儲區了,能夠經過ipcs -m查看當前共享存儲區狀態
第一個鍵值就是傳入的key,shmid標識惟一共享內存段,擁有者權限字節就很少說了額,這個nattch是指當前有多少個進程鏈接到該共享存儲區
nattch:只建立共享存儲區是不夠的,你須要把它和進程連接,才能讓進程的地址空間中的一段地址映射到共享內存段上。
這就講一下用什麼函數連接共享存儲區,須要注意的是,兩個進程都須要連接才能夠,建立共享存儲區的進程不會自動鏈接,也須要調用連接函數
每有一個進程調用這個函數,就會使nattch增長1,返回值由於是個空類型的指針經常須要強制轉換
連接使用完以後就斷開是個好習慣,並且對銷燬共享存儲空間也好
最後仍是要用到shmctl函數來刪除共享存儲區
事已至此,基本操做就說完了,廢話少說,show me the code
個人程序分爲comm.h(公共頭文件) comm.c(封裝基本函數) server.c(簡易服務器端) 一共3個文件
功能主要實現了簡單的字符串共享?父進程寫入,子進程打印,就這麼簡單
結果圖並看不出什麼鬼
comm.h
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <string.h>
4 #include <sys/ipc.h>
5 #include <unistd.h>
6 #include <sys/shm.h>
7 #include <errno.h>
8 #include <stdlib.h>
9
10
11 #define _PATH_NAME_ "/tmp"
12 #define _PROJ_ID_ 0x6666
13
14
15
16 static int comm_create_ssm(int flags,size_t size); 17 int create_shm(size_t size); 18 int get_shm(); 19 char *shm_at(int shm_id); 20 void destory_shm(int shm_id); 21 int shm_dt(char *addr);
comm.c
1 #include "comm.h"
2
3
4 static int comm_create_shm(int flags,size_t size) 5 { 6 key_t _key=ftok(_PATH_NAME_,_PROJ_ID_); 7 if(_key<0) 8 { 9 printf("%d:%s",errno,strerror(errno)); 10 } 11 int shm_id; 12 if((shm_id=shmget(_key,size,flags))<0) 13 { 14 printf("shmget error,%d:%s",errno,strerror(errno)); 15 } 16 return shm_id; 17 } 18
19
20 int create_shm(size_t size) 21 { 22 int flags=IPC_CREAT |IPC_EXCL; 23 return comm_create_shm(flags,size); 24 } 25
26 int get_shm() 27 { 28 int flags=IPC_CREAT; 29 return comm_create_shm(flags,0); 30 } 31
32 char *shm_at(int shm_id) 33 { 34 return (char *)shmat(shm_id,NULL,0); 35 } 36 int shm_dt(char *addr) 37 { 38 return shmdt(addr); 39 } 40
41 void destory_shm(int shm_id) 42 { 43 shmctl(shm_id,IPC_RMID,0); 44 }
server.c
1 #include "comm.h"
2
3
4
5 int main() 6 { 7 int pid=fork(); 8 if(pid>0) 9 { 10 //father
11 int shm_id=create_shm(4096); 12 char *buf=shm_at(shm_id); 13 int i=0; 14 while(i<4096) 15 { 16 sleep(1); 17 buf[i]='A'; 18 i++; 19 buf[i]='\0'; 20 } 21 } 22 else
23 { 24 //child
25 int shm_id=get_shm(); 26 char *buf=shm_at(shm_id); 27 while(1) 28 { 29 sleep(1); 30 printf("%s\n",buf); 31 } 32 } 33 return 0; 34 }