美文网首页
初窥linux共享内存

初窥linux共享内存

作者: bailongxian | 来源:发表于2016-10-12 21:18 被阅读112次

共享内存的linux IPC的一个方式。最简单的解释就是同一段物理内存被映射到不同进程的地址空间。任和一个被映射的进程对该内存的写操作对其他被映射是可见的。
可以在命令查看当前系统共享内存的信息。


下面我们有4个文件,分别是公共文件,shm_write(创建共享内存) shm_read(读取共享内存内容) shm_clean(清除共享内存内容) common.h一个公共文件

common.h

  1 #ifndef _COMMON_H
  2 #define _COMMON_H
  3 
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <sys/shm.h>
  7 #include <stdlib.h>
  8 
  9 #define SHM_KEY         0x00000010
 10 #define BUFFSIZE        0x00001000
 11 
 12 #define SHM_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
 13 
 14 struct shm_mm
 15 {
 16         int num;
 17         char buff[BUFFSIZE];
 18 };
 19 
 20 #endif

shm_write.c

  1 #include "common.h"
  2 #include <stdio.h>
  3 
  4 int main()
  5 {
  6         int shmid;
  7         shmid = shmget(SHM_KEY, sizeof(struct shm_mm), IPC_EXCL|IPC_CREAT|SHM_PERMS);
  8         if(shmid == -1)
  9         {
 10                 printf("shmget failed\n");
 11                 exit(1);
 12         }
 13 
 14         struct shm_mm *pshm = shmat(shmid, NULL, 0);
 15         if(pshm == (void*)-1)
 16         {
 17                 printf("shmat failed\n");
 18                 exit(2);
 19         }
 20 
 21         pshm->num = 100;
 22         for(int i = 0; i < 10 && i < BUFFSIZE; i++)
 23         {
 24                 pshm->buff[i] = 'a';
 25         }
 26 
 27 }

shm_read.c

  1 #include "common.h"
  2 #include <stdio.h>
  3 
  4 int main()
  5 {
  6         int shmid;
  7         shmid = shmget(SHM_KEY,0, 0);
  8         if(shmid == -1)
  9         {
 10                 printf("shmget failed\n");
 11                 exit(1);
 12         }
 13 
 14         struct shm_mm *pshm = shmat(shmid, NULL, 0);
 15         if(pshm == (void*)-1)
 16         {
 17                 printf("shmat failed\n");
 18                 exit(2);
 19         }
 20 
 21         printf("num=%d\n", pshm->num);
 22         for(int i = 0; i < 10 && i < BUFFSIZE; i++)
 23         {
 24                 printf("%c\t", pshm->buff[i]);
 25         }
 26          printf("\n");
 27 
 28         getchar();
 29         return 0;
 30 }

shm_clean.c

  1 #include "common.h"
  2 #include <stdio.h>
  3 
  4 int main()
  5 {
  6         int shmid = shmget(SHM_KEY, 0, 0);
  7         if(-1 == shmid)
  8         {
  9                 printf("shmget failed\n");
 10                 exit(0);
 11         }
 12         int ret = shmctl(shmid, IPC_RMID, 0);
 13         if(-1 == ret)
 14         {
 15                 printf("shmctl failed\n");
 16                 exit(1);
 17         }
 18         return 0;
 19 }

![read_out.png](https://img.haomeiwen.com/i541012/8ff9b7b6ec4b5676.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我们运行shm_write进程
查看当前系统的共享内存

2016-10-10 23-52-41屏幕截图.png

我们可以看到最后一行, 第一列的就是我们代码里面的SHM_KEY 权限也是我们自己设定的 SHM_PERMS, 大小是sizeof(shm_mm)。 因为shm_write进程以退出,所以现在attach在该内存的进程数量为0。
我们启动shm_read

read_out.png

read进程读到了write写进去的数据.
现在我们可以启动clean进程清除刚才创建的贡献内存。也可以用命令 ipcrm -m shmid 清除掉对于的共享内存。

通过上述实现,我们看到,当进程退出后,内核自动会把该进程和共享内存的映射给清掉,就是我们通过ipcs -m 看到的attach的子段。如果我们想在进程不退出就把这个映射这清掉。通过调用shmdt即可。

和其他共享数据一下,当多个进程对同一个共享内存进行读写的时候,仍然会有竞争。所以我们需要一些如信号量,进程锁等高级的进程同步控制原语来进行同步操作。
当然,共享内存还受到一些参数的影响.
/proc/sys/kernel/shmall:限制系统用在共享内存上的内存总页数。注意是页数,单位为4k。
/proc/sys/kernel/shmmax:限制一个共享内存段的最大长度,字节为单位。
/proc/sys/kernel/shmmni:限制整个系统可创建的最大的共享内存段个数。

相关文章

  • 初窥linux共享内存

    共享内存的linux IPC的一个方式。最简单的解释就是同一段物理内存被映射到不同进程的地址空间。任和一个被映射的...

  • Linux共享内存

    这里介绍Linux下常见的共享内存技术。 1、 Linux XSI 的 IPC 下的共享内存机制 Linux XS...

  • Linux虚拟内存技术初窥

    1. 为什么要用虚拟内存 总所周知,从做系统的主要作用是对计算机资源的管理以及程序调度,者其中就包括对内存的管理。...

  • 共享内存原理

    Linux的2.2.x内核支持多种共享内存方式,如mmap()系统调用,Posix共享内存,以及系统V共享内存。 ...

  • 共享内存

    Linux进程间通信 - 共享内存

  • 深信服一面C++

    首先自我介绍 Linux中创建共享内存的方式?共享内存中起始地址是不是按照页的大小对齐?创建共享内存的时候物理页一...

  • 深信服一面C++

    首先自我介绍 Linux中创建共享内存的方式?共享内存中起始地址是不是按照页的大小对齐?创建共享内存的时候物理页一...

  • Linux共享内存

    共享内存是常用的进程之间的通信,两个进程可以直接共享访问同一块内存区域 一、共享内存的实现步骤如下: (1)创建共...

  • 探讨一下 Linux 共享内存的 N 种方式

    关于 Linux 共享内存,写得最好的应该是宋宝华的 《世上最好的共享内存》[https://cloud.tenc...

  • android匿名共享内存Ashmem(c库接口)

    Ashmem Android系统的匿名共享内存Ashmem驱动程序利用了Linux的共享内存子系统导出的接口来实现...

网友评论

      本文标题:初窥linux共享内存

      本文链接:https://www.haomeiwen.com/subject/glivyttx.html