共享内存

共享内存(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网络服务管理命令

    netstat命令 示例:查看指定的服务是否开启netstat | grep ssh | grep -v grep 网络下载器————wget wget是一个Linux环境下用于从WWW上提取文件的工 ...

  2. JavaWeb_反射

    一个类有多个组成部分,例如:成员变量,方法,构造方法等.反射就是加载类,并解剖出类的各个组成部分. 编程时什么情况下才需要加载类,并解剖出累的各个组成部分呢? 反射是用来做框架的. 从配置文件中解读类 ...

  3. C++笔记--类型和声明

    布尔量 Eg: bool b1=a==b;//这个例子中,=是赋值,==是判断是否相等,所以先是判断是否相等,a如果等于b,b1的值就是true,否则就是false了 Bool经常被用作检查某些条件是 ...

  4. [译]Javascript中的函数

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  5. 重建freescale 4.6.2 multilib toolchain

    patch和crosstool-ng 可以从下面的网址下载, https://community.freescale.com/thread/386450 不过估计你会失望的,改了脚本,编译了后发现不对 ...

  6. 无废话MVC入门教程笔记

    自学mvc,看了园子里李林峰写的李林峰写的无废话MVC入门教程笔记,现在有的平时忽略的或是不太清楚的点记下来 1,Html.DropDownList //服务端写法 @{ //下拉列表的值 List& ...

  7. jQuery的选择器+实例

    返回目录 jQuery的冒号选择器 表单  :input :text :password :radio :checkbox :submit :image :reset :button :file :h ...

  8. python文件上传的三种方式

    def upload(request): return render(request, 'upload.html') def upload_file(request): username = requ ...

  9. 659. Split Array into Consecutive Subsequences

    You are given an integer array sorted in ascending order (may contain duplicates), you need to split ...

  10. CENSORING——AC 自动机

    题目 [题目描述] FJ 为它的奶牛订阅了很多杂志,balabala.......,其中有一些奶牛不宜的东西 (比如如何煮牛排). FJ 将杂志中所有的文章提取出来组成一个长度最多为 $ 10^5 $ ...