博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
System V 共享内存区
阅读量:6606 次
发布时间:2019-06-24

本文共 4438 字,大约阅读时间需要 14 分钟。

1、概述

  系统调用mmap通过映射一个普通文件实现共享内存。System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件。执行过程是先调用shmget,再调用shmat。对于每个共享的内存区,内核维护如下的信息结构,定义在<sys/shm.h>头文件中。

1 struct shmid_ds { 2   struct ipc_perm shm_perm;     /* operation perms */ 3   int shm_segsz;            /* size of segment (bytes) */ 4   time_t shm_atime;          /* last attach time */ 5   time_t shm_dtime;          /* last detach time */ 6   time_t shm_ctime;          /* last change time */ 7   unsigned short shm_cpid;      /* pid of creator */ 8   unsigned short shm_lpid;      /* pid of last operator */ 9   short shm_nattch;          /* no. of current attaches */10   /* the following are private */11   unsigned short shm_npages;      /* size of segment (pages) */12   unsigned long *shm_pages;       /* array of ptrs to frames -> SHMMAX */ 13   struct vm_area_struct *attaches;   /* descriptors for attaches */14 };

参考网址:

2、System V 共享内存区API

  使用共享内存的流程:

   1.进程必须首先分配它。
   2.随后需要访问这个共享内存块的每一个进程都必须将这个共享内存绑定到自己的地址空间中。
   3.当完成通信之后,所有进程都将脱离共享内存,并且由一个进程释放该共享内存块。

#include 
#include
/*创建一个新的内存共享区或者访问一个已经存在的共享内存区返回共享内存区标识符*/int shmget(key_t key, size_t size, int shmflg);/*创建或打开一个共享内存区后,调用shmat把它连接到调用进程的地址空间*/void *shmat(int shmid, const void *shmaddr,int shmflg);/*当一个进程完成某个共享内存区的使用时,调用shmdt断开这个内存区*/int shmdt(const void *shmaddr);/*对内存区进行多种操作cmd取值:IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它IPC_SET:给指定的共享内存区设置其shmid_ds结果成员IPC_STAT:通过buff参数向调用者返回所指定共享内存区当前的shmid_ds结构*/int shmctl(int shmid, int cmd, struct shmid_ds *buf);

调用System V API编写程序进行测试:

程序1:调用shmget函数使用指定的路径名和长度创建一个共享内存区,程序如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 7 #define SVSHM_MODE (SHM_R | SHM_W | SHM_R>>3 | SHM_R>>6) 8 9 int main(int argc,char *argv[])10 {11 int c,id,oflag;12 char *ptr;13 size_t length;14 oflag = SVSHM_MODE | IPC_CREAT;15 while(( c = getopt(argc,argv,"e")) != -1)16 {17 switch(c)18 {19 case 'e':20 oflag |= O_EXCL;21 break;22 }23 }24 if (optind != argc -2)25 {26 printf("usage: shmget [-e]
.\n");27 exit(0);28 }29 length = atoi(argv[optind + 1]);30 //创建由用户指定其名字和大小的共享内存区31 id = shmget(ftok(argv[optind],0),length,oflag);32 //把该内存区连接到当前进程的地址空间33 ptr = shmat(id,NULL,0);34 exit(0);35 }

程序2:调用shmctl指定IPC_RMID命令,从系统中删除一个共享内存区,程序如下:

1 #include 
2 #include
3 #include
4 #include
5 6 #define SVSHM_MODE (SHM_R | SHM_W | SHM_R>>3 | SHM_R>>6) 7 8 int main(int argc,char* argv[]) 9 {10 int id;11 if(argc != 2)12 {13 printf("usage: shmrmid
\n");14 exit(0);15 }16 //打开共享内存区17 id = shmget(ftok(argv[1],0),0,SVSHM_MODE);18 //从系统中删除由id标识的共享内存区19 shmctl(id,IPC_RMID,NULL);20 exit(0);21 }

程序3:往共享内存区中写入一个模式,调用shmctl指定IPC_STAT命令格式,程序如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 7 #define SVSHM_MODE (SHM_R | SHM_W | SHM_R>>3 | SHM_R>>6) 8 9 int main(int argc,char *argv[])10 {11 int i,id;12 struct shmid_ds buff;13 unsigned char *ptr;14 if(argc != 2)15 {16 printf("usage: shmwrite
.\n");17 exit(0);18 }19 id = shmget(ftok(argv[1],0),0,SVSHM_MODE);20 ptr = shmat(id,NULL,0);21 shmctl(id,IPC_STAT,&buff); //获取共享内存区大小22 for(i=0;i

程序4:从共享内存去中读出模式,程序如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 7 #define SVSHM_MODE (SHM_R | SHM_W | SHM_R>>3 | SHM_R>>6) 8 9 int main(int argc,char *argv[])10 {11 int i,id;12 struct shmid_ds buff;13 unsigned char c,*ptr;14 if(argc != 2)15 {16 printf("usage: shmread
.\n");17 exit(0);18 }19 id = shmget(ftok(argv[1],0),0,SVSHM_MODE);20 ptr = shmat(id,NULL,0);21 shmctl(id,IPC_STAT,&buff);22 for(i=0;i

 3、System V 与Posix 共享内存区

  二者的差别是:

(1)Posix共享内存区是先调用shm_open然后再调用mmap,System V 共享内存区是先调用shmget再调用shmat。

(2)Posix共享内存区对象的大小可在任何时刻通过ftruncate修改,而System V 共享内存区对象的大小是在调用shmget创建时固定下来的。

 

 

转载于:https://www.cnblogs.com/Anker/archive/2013/01/20/2868357.html

你可能感兴趣的文章
iphone导航控制器的开发与使用
查看>>
debian python library re-install
查看>>
如何用转义来给JS添加的input元素设置单引号
查看>>
HTTP要被抛弃? 亚洲诚信携手宝塔开启HTTPS加密快速通道
查看>>
6.6 tar打包
查看>>
Spring MVC核心技术
查看>>
TCP协议如何保证传输的可靠性
查看>>
Spring Cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
查看>>
软件开发各阶段交付物列表
查看>>
ntp服务器的搭建
查看>>
六、nginx搭建织梦DedeCms网站
查看>>
Tair学习小记
查看>>
网卡绑定(服务器&&交换机),缓存服务器Squid架构配置
查看>>
web网站加速之CDN(Content Delivery Network)技术原理
查看>>
sed的基本用法
查看>>
一个不错的shell 脚本入门教程
查看>>
Ansible之playbook的使用
查看>>
ansible模块批量管理
查看>>
redis命令 - GET
查看>>
httpd.conf的基本设置
查看>>