初窥linux共享内存

共享内存的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](http://upload-images.jianshu.io/upload_images/541012-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:限制整个系统可创建的最大的共享内存段个数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容