共享内存

共享内存(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()返回的地址指针。

/*
* a.c
* write a random number between 0 and 999 to the shm every 1 second
*/
#include<stdio.h>
#include<unistd.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<error.h>
int main(){
int shm_id;
int *share;
int num;
srand(time(NULL));
shm_id = shmget (, getpagesize(), IPC_CREAT);//shm_id 就是 # ipc -m 命令查询到的 linux中共享内存的keyid吧 注意运行结束后清理掉 使用ipcrm -m shm_id 清理
if(shm_id == -){
perror("shmget()");
}
share = (int *)shmat(shm_id, , );
while(){
num = random() % ;
*share = num;
printf("write a random number %d\n", num);
sleep();
}
return ;
}
/*
* b.c
* read from the shm every 1 second
*/
#include<stdio.h>
#include<unistd.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<error.h>
int main(){
int shm_id;
int *share;
shm_id = shmget (, getpagesize(), IPC_CREAT);
if(shm_id == -){
perror("shmget()");
}
share = (int *)shmat(shm_id, , );
while(){
sleep();
printf("%d\n", *share);
}
return ;
}

运行观察结果:

运行时候通过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. Linux expect命令

    一.简介 通过Shell可以实现简单的控制流功能,但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能.而就使用来实现这种功能的工具.Ex ...

  2. GCD学习(七) dispatch_apply

    dispathc_apply 是dispatch_sync 和dispatch_group的关联API.它以指定的次数将指定的Block加入到指定的队列中.并等待队列中操作全部完成. NSArray ...

  3. Entity Framework Tutorial Basics(23):Add Single Entity

    Add New Entity using DBContext in Disconnected Scenario: In this chapter you will learn how to add n ...

  4. 断电操作导致的jboss项目部署失败------从早上九点一直到下午4点才解决

    虚拟机jboss可以连接成功,项目也可以正常编译成功.但是,去访问backstop网址的时候,就是,显示,无法访问该网站.访问9990的jboss服务器时,也是显示无法访问该网站. 项目代码是没问题的 ...

  5. struts1和struts2之间的区别

    从action类上分析:1.Struts1要求Action类继承一个抽象基类.Struts1的一个普遍问题是使用抽象类编程而不是接口. 2. Struts 2 Action类可以实现一个Action接 ...

  6. CodeForces 478D Red-Green Towers (DP)

    题意:给定 n 块红砖,m 块绿砖,问有多少种方式可以建造成最高的塔,每一层颜色必须一样. 析:首先要确定最高是多少层h,大约应该是用 h * (h+1) <= (m+n) * 2,然后dp[i ...

  7. 解决java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext问题

    使用ClassPathXmlApplicationContext加载项目时, ClassPathXmlApplicationContext context = new ClassPathXmlAppl ...

  8. java反射机制的进一步理解

    承上一篇. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

  9. 2015年第六届蓝桥杯省赛试题(JavaA组)

    1.结果填空 (满分3分)2.结果填空 (满分5分)3.结果填空 (满分9分)4.代码填空 (满分11分)5.代码填空 (满分13分)6.结果填空 (满分17分)7.结果填空 (满分21分)8.程序设 ...

  10. metasploit 读书笔记-EXPLOITATION

    一、渗透攻击基础 1.常用命令 show exploits 显示Meta框架中所有可用的渗透攻击模块。 show options 显示模块所需要的各种参数 back 返回Meta的上一个状态 sear ...