当前位置: 首页 > 编程日记 > 正文

linux进程间通信:system V 共享内存

文章目录

        • 思维导图如下
        • 通信原理
        • 优势
        • 运行流程
        • 编程接口
        • 编程实例

思维导图如下

在这里插入图片描述

通信原理

  • 多个进程共享物理内存的同一块区域(通常称之为“段”:segment)
  • 抛弃了内核态消息转存处理的过程,让两个进程直接通过一块内存进行通信

我们普通的像PIPE,FIFO,消息队列等的通信方式如下图:
在这里插入图片描述
这种方式的通信不论读写,都需要内核态(系统调用 read,write,pipe,mkfifo,msgget,msgsnd,msgrcv等)的介入,而且都需要经过数据从虚拟地址空间到物理地址空间的拷贝。
而共享内存的通信方式则都避免了以上的通信问题,直接为两个进程开辟相同的内存空间进行数据交互。
在这里插入图片描述

优势

  • 减少了内存的拷贝(从用户拷贝到内核,从内核拷贝到用户)
  • 减少了2次系统调用(系统调用比较消耗性能,因为CPU处理系统调用时需要从用户态切换到内核态),提高了系统性能

运行流程

  • 获取共享内存对象的ID
  • 将共享内存映射至本进程虚拟内存空间的某个区域(每个用户进程操作系统都有3G的虚拟进程空间)
  • 不同进程对这块内存进行读写、传输数据
  • 当进程不再使用这块共享内存时,解除映射关系
  • 当没有进程需要共享内存的时候,则删除该共享内存

编程接口

  • 获取共享内存的对象ID ,创建或打开一个共享内存对象
    a. 头文件<sys/types.h> <sys/shm.h>
    b. int shmget (key_t key, size_t size, int shmflg);
    c. 函数参数

    • key IPC对象的键值,一般为IPC_PRIVATE 或者ftok返回的key值
    • size 共享内存的大小,一般为物理内存页(4K)的整数倍
    • shmflg
      IPC_CREAT :如果不存在指定的key值,那么就创建一个
      IPC_EXCL: 若key值指定的内存存在,且指定了IPC_CEAT,则回复EXIST错误
      IPC_HUGETLB 使用巨页(huge page)

    d. 返回值:共享内存的标识ID

  • 映射共享内存:
    a. 头文件 <sys/shm.h>
    b. void *shmat(int shmid,const void *shmaddr,int shmflg);
    c. 功能:将shmid标识的共享内存引入到当前进程的虚拟地址空间
    d. 函数参数:

    • shmid 共享内存的IPC对象ID
    • shmaddr
      若为NULL:共享内存会被attach到一个合适的虚拟地址空间,建议使用NULL
      不为NULL:系统会根据参数以及地址边界对齐等分配一个合适的地址
    • shmflg
      IPC_RDONLY:附加只读权限,不指定的话返回默认是读写权限
      IPC_REMAP:替换位于shmaddr处的任意既有映射(共享内存的段或者内存映射)
      SHM_RND:将shmaddr四舍五入为SHMMLBA字节的倍数

    e. 返回值:共享内存段的地址

  • 解除共享内存映射
    a. 头文件 <sys/shm.h>
    b. int shmdt(const void * shmaddr);
    c. 功能:解除内粗映射,将共享内存分离出当前进程的地址空间
    d. 函数参数:

    • shmaddr 共享内存地址

    e. TIPS:

    • 通过fork创建的子进程会继承父进程所附加的共享内存,父子进程可以通过共享内存进行IPC通信,在exec系统调用中,所有附加的共享内存段都会被分离
    • 函数shmdt仅仅是使进程和共享内存脱离关系,将共享内存的引用计数是减1
    • 当共享内存的引用计数为0的时候,调用shmctl的IPC_RMID命令才会删除共享内存
  • 设置共享内存属性
    a. 头文件 <sys/shm.h>
    b. int shmctl(int shmid,int cmd,struct shmid_ds *buf);
    c. 函数功能:获取/设置共享内存对象属性
    d. 函数参数
    - shmid 共享内存对象的ID
    - cmd:
    IPC_RMID :删除共享内存及关联的shmid_ds数据结构
    IPC_STAT: 将该共享内存关联的shmid_ds数据结构拷贝到参数buf中
    IPC_SET: 使用buf中的数据更新与该共享内存对象相关联的shmid_ds
    IPC_INFO:获取系统共享内存相关的信息
    IPC_LOCK: 将一个共享内存段锁进内存,防止被swap出去
    IPC_UNLOCK: 将一个共享内存解锁

  • shmid_ds *buf数据结构如下

    struct shmid_ds {struct ipc_perm  shm_perm;     /* operation permissions */int              shm_segsz;    /* size of segment in bytes */pid_t            shm_lpid;     /* pid of last shm op */pid_t            shm_cpid;     /* pid of creator */short            shm_nattch;   /* # of current attaches */time_t           shm_atime;    /* last shmat() time*/time_t           shm_dtime;    /* last shmdt() time */time_t           shm_ctime;    /* last change by shmctl() */void            *shm_internal; /* sysv stupidity */};
    

编程实例

写端shm_write.c:

#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main()
{//key_t key = ftok("./",111);key_t key = 12345;//根据key值生成共享内存对象的唯一标识int shm_id = shmget(key,4096,IPC_CREAT|0666);//将当前进程加入共享内存,这里设置共享内存地址为NULL时//系统会自动为当前进程分配一个合适的内存空间,并返回共享内存的地址char *shm_p = shmat(shm_id , NULL, 0);memset (shm_p,0,4096);//从标准输入获取内容到共享内存的地址fgets(shm_p,4096,stdin);//等待输入完成,删除共享内存sleep(10);//当前进程创建的共享内存引用计数为0的时候,删除共享内存shmctl(shm_id,IPC_RMID,NULL);return 0;
}

读端shm_read.c

#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main() {
//    key_t key = ftok("./",111);key_t key = 12345;int shm_id = shmget(key, 4096, 0666);//和写端访问到了相同的共享内存区域,并获取内容存放到指针变量char *shm_p = shmat(shm_id , NULL, 0);printf("From SHM: %s\n",shm_p);//删除当前进程与共享内存的映射关系,同时共享内存的引用计数减一shmdt(shm_p);return 0;
}

通过命令ipcs -m可以查看系统共享内存
在这里插入图片描述
需要先执行写入,再去运行读端读出;以上输出如下:
在这里插入图片描述

相关文章:

python函数手册68_直接在python中检索68个内置函数?

Python 3.5中的一种方法是列出具有__module__属性的对象,并将其设置为builtins和lowercase name&#xff1a;>>> sorted(k for k, v in vars(__builtins__).items()if k.islower() and getattr(v, __module__, ) builtins)[__build_class__, __import__, abs, all, a…

《深入理解Java虚拟机》笔记3

垃圾收集算法 (1)标记清除 根据根搜索确定对象是否已死&#xff0c;已死对象标记&#xff0c;然后一起清除。 这个其实不算什么算法&#xff0c;最正常想法应该就是这样。但是&#xff0c;缺点 是效率不高&#xff0c;如果有很多不连续的小对象需要回收&#xff0c;会花好多时间…

Step-By-Step在AIX上安装Oracle RAC

最近遇到一个项目&#xff0c;是在AIX5.3上安装ORACLE 9i RAC&#xff0c;说实话&#xff0c;ORACLE俺压根就没有接触过&#xff0c;我也是临危受命。感觉如同当年实施AS400的XSM项目一般。无奈&#xff0c;下载了N多本REDBOOK开始研究&#xff0c;终于有了些眉目&#xff0c;找…

Python中输出字体的颜色设置

1.实现过程 终端的字符颜色是用转义序列控制的&#xff0c;是文本模式下的系统显示功能&#xff0c;和具体的语言无关。控制字符颜色的转义序列是以ESC开头,即用\033来完成 2.书写过程开头部分: \033[显示方式;前景色;背景色m结尾部分: \033[0m注意&#xff1a;开头部分的三个…

linux进程间通信:system V 信号量

文章目录概念描述通信原理编程接口使用流程编程案例概念描述 英文&#xff1a;semaphore 简称SEM&#xff0c;主要用来进行进程间同步本质&#xff1a;内核维护的一个正整数&#xff0c;可对其进行各种/-操作分类&#xff1a;systemV 信号量、POSIX 有名信号量、POSIX 无名信号…

设计模式总结1

1.代码不是没有错误就是最好的 &#xff08;1&#xff09;命名要规范-------取一个好的名字。 &#xff08;2&#xff09;代码少做无用功。 &#xff08;3&#xff09;注意逻辑错误。 &#xff08;4&#xff09;面向对象&#xff1a;可维护、可复用、可扩展、灵活性好。 2.简单…

mysql 单选字段_mysql字段类型

学习自 https://www.cnblogs.com/jennyyin/p/7895010.html&#xff0c;感谢原博主的奉献mysql支持多种类型&#xff0c;大致可以分为三类&#xff1a;数值、字符串、日期/时间。数值类型类型大小范围(有符号)范围(无符号)用途tinyint1字节(-128, 127)(0,255)小整数值smallint2字…

ios时间差,以时间格式显示

为什么80%的码农都做不了架构师&#xff1f;>>> NSDate *nowDate [[NSDate alloc]init]; double diffTime [nowDate timeIntervalSinceDate:preDate]; int diffHour diffTime / (60*60); int diffMin ( diffTime - diffHour*(60*60) ) / (60); int diffSec…

深入理解C++中public、protected及private用法

深入理解C中public、protected及private用法 这篇文章主要介绍了C中public、protected及private用法,对于C面向对象程序设计来说是非常重要的概念,需要的朋友可以参考下初学C的朋友经常在类中看到public&#xff0c;protected&#xff0c;private以及它们在继承中表示的一些访问…

v-vim 代码批量缩进,字符串精确查找及替换

vim中代码批量缩进 有如下两种办法&#xff0c;主要依靠>和<字符来进行 缩进的单位通过设置~/.vimrc,添加如下行 set tabstop4 "设定tab宽度为4个字符 set shiftwidth4 "设定自动缩进为4个字符 set expandtab "用space替代tab的输入 set noexpandtab &q…

Codeforces Round #228 (Div. 1)B

进制构造 这里用了十进制 有点像串并联 每一位代表的数分开表示出来再把每一位的数并起来 比如892 就是800902 800又可分为8*10*10。。。 1 #include <iostream>2 #include<cstdio>3 #include<cstring>4 #include<algorithm>5 #include<stdlib.h&g…

javaweb实现mysql备份功能_java web 实现mysql 数据库备份、恢复

如题&#xff0c;由于项目需要&#xff0c;研究并实现了java web的 mysql数据库的备份、下载、恢复功能&#xff0c;中间遇到一些问题&#xff0c;耗费了不少时间&#xff0c;下面让我一一道来&#xff1a;背景介绍&#xff1a;window 7系统mysql 5.7eclipsespring mvctomcat 7…

在windows8 上安装framework 3.5

在电脑上装了windows8 的双系统后&#xff0c;为了装上Windows Live Writer&#xff0c;需要安装framework3.5.在线安装等了很久都装不上&#xff0c;下载的安装包不能用&#xff0c;提示需要framework3.5的支持。死循环啊 。搜索找到离线更新的方法&#xff0c; 离线更新方法&…

C#第一章笔记

第一个C#程序 namespace 是C#中组织代码的方式&#xff0c;它的作用那个类似java中的包 using 在Java中作用如果导入其他包 应该是用import关键字而在C#中应使用using关键字来引用 class关键字 与java一样C#也是一门面向对象的得语言&#xff0c;使用class关键字来表示类 Main&…

linux进程间通信:system V 信号量和共享内存实现进程间同步

关于信号量和共享内存的相关描述已经在前几篇提到过&#xff1b; 信号量&#xff1a;即内核维护的一个正整数&#xff0c;可以使用内核提供的p/v接口进行该正整数的/-操作&#xff0c;它主要用来表示系统中可用资源的个数&#xff0c;协调各个进程有序访问资源&#xff0c;防止…

mysql三次握手_一文彻底搞懂 TCP三次握手、四次挥手过程及原理

原创文章首发于公众号&#xff1a;「码农富哥」&#xff0c;欢迎收藏和关注&#xff0c;如转载请注明出处&#xff01;TCP 协议简述TCP 提供面向有连接的通信传输&#xff0c;面向有连接是指在传送数据之前必须先建立连接&#xff0c;数据传送完成后要释放连接。无论哪一方向另…

【转】常见系统中文字体的英文名

http://www.aoao.org.cn/blog/2008/03/fonts-chinese/ http://www.yale.edu/chinesemac/pages/fonts.html Mac OS的一些&#xff1a; 华文细黑&#xff1a;STHeiti Light [STXihei]华文黑体&#xff1a;STHeiti华文楷体&#xff1a;STKaiti华文宋体&#xff1a;STSong华文仿宋&…

手动新增swap分区

1、建立1G的交换分区&#xff08;填充&#xff09; #dd if /dev/zore of /opt/swapfile bs1M count1024 2、设置交换分区文件 #mkswap /opt/swapfile 3、立即启用交换分区文件 #swapon /opt/swapfile 4、系统开机时自动挂载新分区 #vim /etc/fstab 末尾添加&#xff1a;/opt…

js捕获和冒泡

面向对象&#xff1a; 1.单例模式 2.工厂模式 3.构造函数 &#xff08;1&#xff0c;2&#xff0c;3的目的都是生成对象&#xff09; js天生自带的类 object&#xff08;基类&#xff09; 子类&#xff1a;function&#xff08;函数&#xff09; array&#xff08;数组&…

linux进程间通信:system V 信号量 生产者和消费者模型编程案例

生产者和消费者模型&#xff1a; 有若干个缓冲区&#xff0c;生产者不断向里填数据&#xff0c;消费者不断从中取数据两者不冲突的前提&#xff1a; 缓冲区有若干个&#xff0c;且是固定大小&#xff0c;生产者和消费者各有若干个生产者向缓冲区中填数据前需要判断缓冲区是否满…

mysql类exadata功能_几类关系型数据库的数据解决方案

今天聊下几类关系型数据库的数据解决方案,算是抛砖引玉&#xff0c;近期也要对技术方向上做一些扩展&#xff0c;也算是前期的小结吧。13Oracle目前市面上的主流版本应该还是11gR2&#xff0c;记得很多年前有个网站做过一次调查&#xff0c;10g&#xff0c;11g的版本比例差不多…

ZOJ 2723 Semi-Prime ||ZOJ 2060 Fibonacci Again 水水水!

两题水题&#xff1a; 1.如果一个数能被分解为两个素数的乘积&#xff0c;则称为Semi-Prime&#xff0c;给你一个数&#xff0c;让你判断是不是Semi-Prime数。 2.定义F(0) 7, F(1) 11, F(n) F(n-1) F(n-2) (n>2) 让你判断第n项是否能被3整除。 1.ZOJ 2723 Semi-Prime ht…

Lua中的基本函数库

基本函数库为Lua内置的函数库&#xff0c;不需要额外装载assert (v [, message])功能&#xff1a;相当于C的断言&#xff0c;参数&#xff1a;v&#xff1a;当表达式v为nil或false将触发错误,message&#xff1a;发生错误时返回的信息&#xff0c;默认为"assertion failed…

Oracle中的substr()函数 详解及应用

1&#xff09;substr函数格式 (俗称&#xff1a;字符截取函数) 格式1&#xff1a; substr(string string, int a, int b); 格式2&#xff1a;substr(string string, int a) ; 解释&#xff1a; 格式1&#xff1a; 1、string 需要截取的字符串 2、a 截取字符串…

linux进程间通信:POSIX 消息队列

文章目录基本介绍相关编程接口编程实例消息队列通信实例消息队列属性设置实例基本介绍 关于消息队列的基本介绍&#xff0c;前面在学习system V的消息队列时已经有过了解&#xff0c;linux进程间通信&#xff1a;system V消息队列 支持不同进程之间以消息&#xff08;message…

opencv 修改图像数值_opencv 修改图像数值_Python中使用OpenCV读取像素

如何在Python中遍历像素呢&#xff1f;请看代码&#xff1a;import numpy as npimport cv2import matplotlib.pyplot as pltsrc cv2.imread("src.png")gray cv2.cvtColor(src, cv2.COLOR_RGB2GRAY)rows, cols gray.shape[:2]row gray[200]plt.plot(row)# plt.sho…

SQL中返回一个字符串在另一个中存在的次数

ALTER FUNCTION [reg].[f_GetSameStringCntNoSort] ( str1 VARCHAR(100),--源字符串&#xff0c;取该串中的strLen长度的字符是否在目的字符串 str2 VARCHAR(100) --目的字符串 ) RETURNS INT AS BEGIN -- 返回的长度 DECLARE count INT DECLARE returnValue …

自由软件的自由

我相信我的订阅者中有很多是IT从业人员&#xff0c;我们在工作中会使用各种软件&#xff0c;除了微软、苹果等软件巨头的商业软件&#xff0c;还有更多的自由软件。我们使用这些软件构建自己的工作环境&#xff0c;为公司开发运营系统&#xff0c;为客户实现业务流程&#xff0…

c/c++ 拷贝控制 构造函数的问题

拷贝控制 构造函数的问题 问题1&#xff1a;下面①处的代码注释掉后&#xff0c;就编译不过&#xff0c;为什么&#xff1f;&#xff1f;&#xff1f; 问题2&#xff1a;但是把②处的也注释掉后&#xff0c;编译就过了&#xff0c;为什么&#xff1f;&#xff1f;&#xff1f; …

linux进程间通信:POSIX 消息队列 ----异步通信

在上一篇中linux进程间通信&#xff1a;POSIX 消息队列我们知道消息队列中在消息个数达到了队列所能承载的上限&#xff0c;就会发生消息的写阻塞。 阻塞式的通信影响系统效率&#xff0c;进程之间在通信收到阻塞时并不能去做其他事情&#xff0c;而是一直处于阻塞状态。 为了…