共享内存

共享内存(shared memory)是最简单的Linux进程间通信方式之一

使用共享内存,不同进程可以对同一块内存进行读写

由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,同时还避免了多余的内存拷贝,所以,这种方式是效率最高、速度最快的进程间通信方式。

这种最大限度的自由也给共享内存带来了缺点:内核并不提供任何对共享内存访问的同步机制,比如 同时对共享内存的相同地址进行写操作,则后写的数据会覆盖之前的数据。所以,使用共享内存一般还需要使用其他IPC机制(如信号量)进行读写同步与互斥
---------------------

基本原理

了解Linux内存管理机制,就很容易知道共享内存的原理了。

大家知道,内核对内存的管理是以页(page)为单位的,Linux下一般一个page大小是4k

而程序本身的虚拟地址空间是线性的,所以内核管理了进程从虚拟地址空间到起对应的页的映射

创建共享内存空间后,内核将不同进程虚拟地址的映射到同一个页面:所以在不同进程中,对共享内存所在的内存地址的访问最终都被映射到同一页面。下图演示了共享内存的工作机制
---------------------

相关接口
  1)创建共享内存(SHared Memory GET):

  int shmget(key_t key, int size, int flag);
  返回:成功时返回一个和key相关的共享内存标识符,失败范湖范围-1。

  key:为共享内存段命名,多个共享同一片内存的进程使用同一个key。

  size:共享内存容量。

  flag:权限标志位,和open的mode参数一样。

   2)连接到共享内存地址空间(SHared Memory ATtach):

    void *shmat(int shmid, void *addr, int flag);
    返回:返回值即共享内存实际地址。

    shmid:shmget()返回的标识。

    addr:决定以什么方式连接地址。

    flag:访问模式。

  3)从共享内存分离(SHared Memory DeTach):

   int shmdt(const void *shmaddr); 
   返回:调用成功返回0,失败返回-1。

   shmaddr:是shmat()返回的地址指针。

  1. /*
  2. * a.c
  3. * write a random number between 0 and 999 to the shm every 1 second
  4. */
  5. #include<stdio.h>
  6. #include<unistd.h>
  7. #include<sys/shm.h>
  8. #include<stdlib.h>
  9. #include<error.h>
  10. int main(){
  11. int shm_id;
  12. int *share;
  13. int num;
  14. srand(time(NULL));
  15. shm_id = shmget (, getpagesize(), IPC_CREAT);//shm_id 就是 # ipc -m 命令查询到的 linux中共享内存的keyid吧 注意运行结束后清理掉 使用ipcrm -m shm_id 清理
  16. if(shm_id == -){
  17. perror("shmget()");
  18. }
  19. share = (int *)shmat(shm_id, , );
  20. while(){
  21. num = random() % ;
  22. *share = num;
  23. printf("write a random number %d\n", num);
  24. sleep();
  25. }
  26. return ;
  27. }
  1. /*
  2. * b.c
  3. * read from the shm every 1 second
  4. */
  5. #include<stdio.h>
  6. #include<unistd.h>
  7. #include<sys/shm.h>
  8. #include<stdlib.h>
  9. #include<error.h>
  10. int main(){
  11. int shm_id;
  12. int *share;
  13. shm_id = shmget (, getpagesize(), IPC_CREAT);
  14. if(shm_id == -){
  15. perror("shmget()");
  16. }
  17. share = (int *)shmat(shm_id, , );
  18. while(){
  19. sleep();
  20. printf("%d\n", *share);
  21. }
  22. return ;
  23. }

运行观察结果:

运行时候通过ipcs -m查看共享内存的id 的情况   记得要释放掉共享的内存  如果不释放  下次 还是会被占用!!!!!!

取得ipc信息:
ipcs [-m|-q|-s]
-m       输出有关共享内存(shared memory)的信息
-q       输出有关信息队列(message queue)的信息
-s       输出有关“遮断器”(semaphore)的信息
# ipcs -m 
IPC status from  as of 2007年04月10日 星期二 18时32分18秒 CST
T          ID       KEY         MODE         OWNER     GROUP
Shared Memory:
m           0    0x50000d43 --rw-r--r--      root      root
m         501    0x1e90c97c --rw-r-----    Oracle       dba

清理掉共享内存

#   ipcrm 命令   
移除一个消息对象。或者共享内存段,或者一个信号集,同时会将与ipc对象相关链的数据也一起移除。当然,只有超级管理员,或者ipc对象的创建者才有这项权利啦

ipcrm用法 
ipcrm -M shmkey  移除用shmkey创建的共享内存段
ipcrm -m shmid    移除用shmid标识的共享内存段
ipcrm -Q msgkey  移除用msqkey创建的消息队列
ipcrm -q msqid  移除用msqid标识的消息队列
ipcrm -S semkey  移除用semkey创建的信号
ipcrm -s semid  移除用semid标识的信号

Linux IPC 共享内存的更多相关文章

  1. linux IPC共享内存

    共享内存相关函数 获得一个共享存储标识符 #include <sys/ipc.h> #include <sys/shm.h int shmget(key_t key, size_t ...

  2. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...

  3. linux 下共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

  4. linux 进程间通信 共享内存 shmat

    系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是通过shm ...

  5. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  6. 学习笔记:Linux下共享内存的方式实现进程间的相互通信

    一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...

  7. linux 进程间通信 共享内存 mmap

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...

  8. IPC——共享内存

    Linux进程间通信——使用共享内存 下面将讲解进程间通信的另一种方式,使用共享内存.   一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的 ...

  9. linux使用共享内存通信的进程同步退出问题

    两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...

随机推荐

  1. 2用java代码实现冒泡排序算法(转载)

    import java.util.Scanner; public class Maopao { public static void main(String[] args) { System.out. ...

  2. ZROI2018普转提day2t3

    传送门 分析 考试的时候sb了......我们发现可以按照先序遍历将一棵树变成一个序列,而不需要删的数的数量便是最长上升子序列的长度,但是还有一个问题就是如果在5和7之间有3个空的位置就无法填入合法的 ...

  3. Luogu 3761 [TJOI2017]城市

    BZOJ 4890. 在树上断开一条边之后会形成两个联通块,如果要使这一条边接回去之后保持一棵树的形态,那么必须在两个联通块之间各找一个点连接. 那么,对于每一条可能断开的边,它产生的答案是以下两者的 ...

  4. Entity Framework Tutorial Basics(1):Introduction

    以下系列文章为Entity Framework Turial Basics系列 http://www.entityframeworktutorial.net/EntityFramework5/enti ...

  5. 12. git常用语法总结

    git介绍与安装这里不再多说,再说也不如廖雪峰大佬总结的优秀: https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67 ...

  6. Mac下的UI自动化测试 (四)

    在实际写testcase的时候会使用unittest框架,但是在sikuli中需要使用它提供的command来运行,位于/Applications/SikuliX.app/run,使用-r参数指定要运 ...

  7. pandas-如何得到某一个值所在的行

    df[df['列名'].isin([相应的值])]

  8. [SinGuLaRiTy] 贪心题目复习

    [SinGuLaRiTy-1024] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. [POJ 2709] 颜料 (Painter) 题目描述 ...

  9. 【TED演讲】阿帕玛・饶:(幽默的高科技艺术)

    身为艺术家和TED Fellow的阿帕玛・饶对熟悉的事物以惊奇的幽默的方式进行再次想像.通过和索伦・普尔兹的合作,她创作出一系列高科技的艺术作品-一个会发邮件的打字机,一个让你在屏幕上消失而跟踪拍摄你 ...

  10. 【转】oracle远程导入数据库

    源地址:http://blog.chinaunix.net/uid-20980141-id-447996.html