共享内存

共享内存(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. setex()

    设置值和有效期 $redis->setex($key, $expire, $value);//$expire,有效期,单位秒 相当于 SET key value//设置键值 EXPIRE key ...

  2. 树莓派研究笔记(3)-- 安装VNC

    小屏幕太小了,眼睛快看瞎了,必须安装VNC 才行啊. 更新—2018-02-04 最新版本的系统中自带了VNC了,只需要在 菜单 Preferences -> Raspberry Pi Conf ...

  3. Entity Framework Tutorial Basics(34):Table-Valued Function

    Table-Valued Function in Entity Framework 5.0 Entity Framework 5.0 supports Table-valued functions o ...

  4. 自定义select样式

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. 多用户ATM机(面向对象编程)

    let readline = require('readline-sync'); // 清屏函数 let clear = () => process.stdout.write(process.p ...

  6. 百度地图 JS API开发Demo01

    百度地图DEMO     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  7. poj1195(二维树状数组)

    题目链接:https://vjudge.net/problem/POJ-1195 题意:有s*s的矩阵,初始化为全0,有两种操作,单点修改(x,y)的值,区间查询(x,y)的值(l<=x< ...

  8. jquery - min.js /jquery-1.8.3.min.js引入后报错

    解决方法:在“jquery-1.8.3.min.js”文件上,点击鼠标右键,在弹出菜单中选择“myeclipse”->"exclude From Validation",错误 ...

  9. t-sql read xlsx

    How to Read and Load an Excel 2007 or Excel 2010 File Without Using Import/Export Utility To read an ...

  10. Educational Codeforces Round 59 (Rated for Div. 2)

    熬夜爆肝,智商急剧下降 坐标UTC+8晚上23:35开始 晚上脑袋转的慢,非常慢 T1上来先做还花了好几分钟 T2本来是有式子的我TM写数位DP写炸了然后才发现是有公式 T3英语不好,一开始题意没读懂 ...