共享内存

  • 共享内存区域是被多个进程共享的一部分物理内存。
  • 多个进程都可以把共享内存映射到自己的虚拟空间。所有用户空间的进程要操作共享内存,都要将其映射到自己的虚拟空间,通过映射的虚拟内存空间地址去操作共享内存,从而达到进程间的数据通信。
  • 共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容
  • 本身不提供同步机制,可通过信号量进行同步
  • 提升数据处理效率,一种效率最高的IPC机制

共享内存属性信息

struct shmid_ds{
struct ipc_perm shm_perm;
size_t shm_semsz;//共享内存大小
pid_t shm_lpid;//最后一次调用系统pid
pid_t shm_cpid;//pid的创建者的id
shmatt_t shm_nattch;//和共享内存成功映射的数量
time_t shm_atime;//最后一个成功映射的时间
time_t shm_dtime;//最后断开映射的时间
time_t shm_ctime;//最后改变的时间
}

共享内存使用步骤

  • 使用shmget()函数创建共享内存
  • 使用shmat()函数映射共享内存,将这段创建的共享内存映射到具体的进程虚拟内存空间

创建共享内存

#include <sys/shm.h>
itn shmget(key_t key,size_t size,int shmflag);
//返回,成功返回内核中共享内存的表示iD,失败返回-1.
  • 参数

    • key:用户指定的共享内存键值
    • size:共享内存大小
    • shmflg:IPC_CREAT,IPC_EXCL等权限组合
  • erron
    • EINVAL(无效的内存段大小)
    • EEXIST(内存段已经存在,无法创建)
    • EIDRM(内存段已经被删除)
    • ENOENT(内存段不存在)
    • EACCES(权限不够)
    • ENOMEM(没有足够内存创建内存段)

共享内存控制

#include<sys/shm.h>
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
  • 参数

    • shmid:共享内存ID
    • buf:共享内存属性指针
    • cmd
      • IPC_STAT 获取共享内存段属性
      • IPC_SET 设置共享内存段属性
      • IPC_RMID 删除共享内存段
      • SHM_LOCK 锁定共享内存段页面
      • SHM_UNLOCK 解锁锁定

共享内存映射和解除

#include<sys/shm.h>
void shmat(int shmid,char *shmaddr,int shmflg);
int shmdt(char *shmaddr);
//失败返回-1
  • 参数

    • shmid:共享内存ID
    • shmaddr:映射到进程虚拟内存空间的地址,系统自动分配
    • shmflg:弱shmaddr为0,shmflag也是0
      • SHM_RND
      • SHMLBA 地址为2的次方
      • SHM_RDONLY 只读方式连接
  • errno
    • EINVAL 无效的IPC ID值或无效的地址
    • ENOMEM 没有足够的内存
    • EACCES 权限不够
  • 子进程不继承父进程创建的共享内存,大家是共享的,子进程继承父进程映射的地址。

案例:

通过共享内存实现进程间通信

#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "tell.h" int main(void)
{
//创建共享内存
int shmid;
if((shmid=shmget(IPC_PRIVATE,1023,
IPC_CREAT|IPC_EXCL|0777))<0)
{
perror("shmget error");
exit(1);
} pid_t pid;
init();//初始化管道
if((pid=fork())<0)
{
perror("fork error");
exit(1);
}else if(pid>0)
{
//parent process
//进行共享内存的映射
int *pi=(int*)shmat(shmid,0,0);
if(pi==(int*)-1)
{
perror("shmat error");
exit(1);
}
//往共享内存中写入数据
*pi=100;
*(pi+1)=200;
//操作完毕,解除映射
shmdt(pi);
//通知子进程去读取数据
notify_pipe();
destory_pipe();
wait(0);
}else
{
//child process
//子进程阻塞,都带父进程往共享内存写入数据
wait_pipe();
//子进程从共享内存中读取数据
//子进程进行共享内存的映射
int *pi=(int*)shmat(shmid,0,0);
if(pi==(int*)-1)
{
perror("shmat error");
exit(1);
}
printf("start:%d,end:%d\n",*pi,*(pi+1));
//读取完毕解除映射
shmdt(pi);
//删除共享内存
shmctl(shmid,IPC_RMID,NULL); destory_pipe(); }
}

IPC 进程间通信方式——共享内存的更多相关文章

  1. Linux下进程间通信方式——共享内存

    1.什么是共享内存? 共享内存就是允许两个或多个进程共享一定的存储区.就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针.当一个进程改变了这块地址中的内容的时候,其它进程都会察 ...

  2. Linux进程IPC浅析[进程间通信SystemV共享内存]

    Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到 ...

  3. Linux环境进程间通信(五): 共享内存(下)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  4. Linux环境进程间通信(五): 共享内存(上)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  5. 浅析Linux下进程间通信:共享内存

    浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...

  6. Linux进程间通信—使用共享内存

    Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...

  7. IPC最快的方式----共享内存(shared memory)

    在linux进程间通信的方式中,共享内存是一种最快的IPC方式.因此,共享内存用于实现进程间大量的数据传输,共享内存的话,会在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限 ...

  8. linux进程间通信之共享内存篇

    本文是对http://www.cnblogs.com/andtt/articles/2136279.html中共享内存(上)的进一步阐释说说明 1 共享内存的实现原理 共享内存是linux进程间通讯的 ...

  9. Linux IPC实践(8) --共享内存/内存映射

    概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS ...

随机推荐

  1. wms、wmts和wfs的区别

    Web地图服务(WMS)利用具有地理空间位置信息的数据制作地图.其中将地图定义为地理数据可视的表现.这个规范定义了三个操作:GetCapabilities返回服务级元数据,它是对服务信息内容和要求参数 ...

  2. Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game)

    Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game) 亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最 ...

  3. Eclipse新建新的工作空间,将原有的配置全部或部分复制

    1.部分复制 File->Switch workspace->Other...,按下图选择 只复制简单的配置,如cvs之类的信息是不会复制的. 2.全部复制(build path) 在1. ...

  4. JS中FireFox新开窗口预览打印处理的方式

    仅提供思路,勿喷如下↓ /** * 打印方法 * @param dom 要被打印的dom元素 * @param parentClassName 该组件的页面根组件class名 * @param pag ...

  5. s7-200日常使用烂笔头

    这篇文章只是记录我的苦逼自控之路,有些是书上的,有些是自己发现的,不记载网上得出来的一些东西.只为强化记忆以及便于翻阅. 1.今天使用PC\PPI cable线缆连接成功了200,这个线是盗版线,之前 ...

  6. 菜鸟系列Fabric——Fabric 基本概念(1)

    Fabric 基本概念 1.区块链介绍 区块链之所以引来关注是因为比特币开源项目,尤其是比特币价值的飙升,让大家开始关注数字货币以及相关技术.那么区块链究竟是什么? 1.1 区块链定义 狭义上,区块链 ...

  7. Pandas时间序列和分组聚合

    #时间序列import pandas as pd import numpy as np # 生成一段时间范围 ''' 该函数主要用于生成一个固定频率的时间索引,在调用构造方法时,必须指定start.e ...

  8. Linux学习笔记(16)Linux前后台进程切换(fg/bg/jobs/ctrl+z)

    关键词:Linux前后台进程切换,linux进程切换 fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的一.& ...

  9. PHP7 错误及异常机制

    关键词 error 不能在编译期发现的运行期错误,比如试图用 echo 输出一个未赋值的变量,这类问题往往导致程序或逻辑无法继续下去而需要中断: exception 程序执行过程中出现意料之外的情况, ...

  10. 矩阵快速幂(Matrix_Fast_Power)

    一.基础知识(1)矩阵乘法 https://blog.csdn.net/weixin_43272781/article/details/82899737 简单的说矩阵就是二维数组,数存在里面,矩阵乘法 ...