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

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

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 };

参考网址:

As with message queues and semaphore sets, the kernel maintains a special internal data structure for each shared memory segment which exists within its addressing space. This structure is of type shmid_ds, and is defined in linux/shm.h as follows:


/* One shmid data structure for each shared memory segment in the system. */        struct shmid_ds {                struct ipc_perm shm_perm;        /* operation perms */                int     shm_segsz;               /* size of segment (bytes) */                time_t  shm_atime;               /* last attach time */                time_t  shm_dtime;               /* last detach time */                time_t  shm_ctime;               /* last change time */                unsigned short  shm_cpid;        /* pid of creator */                unsigned short  shm_lpid;        /* pid of last operator */                short   shm_nattch;              /* no. of current attaches */                                                  /* the following are private */                unsigned short   shm_npages;     /* size of segment (pages) */                unsigned long   *shm_pages;      /* array of ptrs to frames -> SHMMAX */                 struct vm_area_struct *attaches; /* descriptors for attaches */        };

Operations on this structure are performed by a special system call, and should not be tinkered with directly. Here are descriptions of the more pertinent fields:

shm_perm

This is an instance of the ipc_perm structure, which is defined for us in linux/ipc.h. This holds the permission information for the segment, including the access permissions, and information about the creator of the segment (uid, etc).

shm_segsz

Size of the segment (measured in bytes).

shm_atime

Time the last process attached the segment.

shm_dtime

Time the last process detached the segment.

shm_ctime

Time of the last change to this structure (mode change, etc).

shm_cpid

The PID of the creating process.

shm_lpid

The PID of the last process to operate on the segment.

shm_nattch

Number of processes currently attached to the segment.

 

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创建时固定下来的。

转载地址:http://ccgdl.baihongyu.com/

你可能感兴趣的文章
oracle windows下使用批处理进行exp导出
查看>>
关于奇怪的并行进程分析(一)
查看>>
新书定稿终落成,期待手中留书香
查看>>
【Redis】Java中使用Jedis操作Redis(Maven导入包)、创建Redis连接池
查看>>
WPF 3D 知识点大全以及实例
查看>>
[20161012]数据文件offline马上执行recover
查看>>
HDOJ 1012 u Calculate e
查看>>
[20170104]一条sql优化.txt
查看>>
关闭 Visual Studio 2013 的 Browser Link 功能
查看>>
我的VSTO之路:序
查看>>
【MVP月度主题分享】通过dataV制作实时数据大屏
查看>>
首批获批入驻雄安新区公司名单公布,BAT、京东等48家企业审批通过
查看>>
物联网医疗来了:让患者获得一站式医疗服务
查看>>
Gartner发布独立报告解读大数据问题
查看>>
有了深度学习,传统的机器学习算法没落了吗,还有必要去学习吗?
查看>>
微服务与SOA架构
查看>>
2015.08.26枚举
查看>>
WCF服务端运行时架构体系详解[上篇]
查看>>
教师人事管理系统需求记录
查看>>
调试工具
查看>>