我会用几篇博客总结一下在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 }