【Linux】进程间通信——system V共享内存、共享内存的概念、共享内存函数、system V消息队列、信号量
文章目录
- 进程间通信
- 1.system V共享内存
- 1.1共享内存原理
- 1.2共享内存数据结构
- 1.3共享内存函数
- 2.system V消息队列
- 2.1消息队列原理
- 3.system V信号量
- 3.1信号量原理
- 3.2进程互斥
- 4.共享内存的使用示例
进程间通信
1.system V共享内存
1.1共享内存原理
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。

本质:还是先让不同的进程看到同一份资源。
所以,共享内存是Unix下的多进程之间的通信方法,允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。共享内存本质上是一块物理内存,多个进程通过将同一块物理内存都映射到自己的虚拟地址空间,通过自己的虚拟地址进行访问,实现数据间的共享。
如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。但是需要注意的是,共享内存并未提供锁机制,也就是说,在某一个进程对共享内存的进行读写的时候,不会阻止其它的进程对它的读写。如果要对共享内存的读/写加锁,可以使用信号灯。
1.2共享内存数据结构
struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kernel_time_t shm_ctime; /* last change time */__kernel_ipc_pid_t shm_cpid; /* pid of creator */__kernel_ipc_pid_t shm_lpid; /* pid of last operator */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */
};
Linux的共享内存数据结构是struct shmid_ds,它定义了共享内存的一些重要属性。这个结构体包括以下字段:
struct ipc_perm shm_perm:这个字段包含了操作权限,如读、写和执行等。
int shm_segsz:这个字段表示共享内存段的字节大小。
__kernel_time_t shm_atime:这个字段表示最后一次附加的时间。
__kernel_time_t shm_dtime:这个字段表示最后一次分离的时间。
__kernel_time_t shm_ctime:这个字段表示最后一次更改的时间。
__kernel_ipc_pid_t shm_cpid:这个字段表示创建者的进程ID。
__kernel_ipc_pid_t shm_lpid:这个字段表示最后一次操作共享内存的进程ID。
unsigned short shm_nattch:这个字段表示当前附加到共享内存的进程数。
unsigned short shm_unused:这个字段是用于兼容的,目前未使用。
这个结构体主要用于在Linux内核中描述POSIX共享内存(即System V共享内存)。在用户空间中,通常使用的是shmget(), shmat(), shmdat()等系统调用与内核的POSIX共享内存交互。
1.3共享内存函数
shmget函数

功能:用来创建共享内存
原型: int shmget(key_t key, size_t size, int shmflg);
参数:
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1。
shmat函数

功能:将共享内存段连接到进程地址空间
原型:void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
shmid: 共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
注意:
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
shmdt函数

功能:将共享内存段与当前进程脱离
原型:int shmdt(const void *shmaddr);
参数:
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数

功能:用于控制共享内存
原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

2.system V消息队列
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法。
每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值。
特性方面:IPC资源必须删除,否则不会自动清除, 除非重启,所以system V IPC资源的生命周期随内核。
2.1消息队列原理

System V消息队列的原理是基于消息块的数据结构,可以在进程间传递数据。每个消息块都有一个类型和信息两部分构成。两个进程可以通过System V消息队列互相发送和接收消息。发送消息时,进程将数据块添加到消息队列的队尾,接收消息时,进程从消息队列的队头获取数据块。
需要注意的是,System V消息队列的资源必须自行删除,否则不会自动清除,因为System V IPC资源的生命周期是随内核的。同时,消息队列数据结构也可能会存在大量的消息队列,系统也必须为消息队列维护相关的内核数据结构。
3.system V信号量
3.1信号量原理
System V信号量集(也称为信号量)的原理是基于一种数据操作锁(相当于资源计数器),用于同步和协调多个进程之间的数据交换。它自身不具备数据交换功能。
信号量的工作原理基于两种原子性操作:wait(p)和signal(v)。 当一个进程进行wait(p)操作时,如果信号量的值大于0,则该进程可以继续执行并使用一个资源,将信号量的值减1;如果信号量的值为0,则该进程会被阻塞,直到其他进程释放资源,使信号量的值大于0为止。当一个进程进行signal(v)操作时,如果信号量的值小于等于0,则该进程可以继续执行并使用一个资源,将信号量的值加1;如果信号量的值大于0,则进程不会得到资源,因为已有其他进程在使用资源。
信号量的作用是维护资源的互斥和多进程的同步访问,以确保在一个时间点只有一个进程可以访问共享资源,从而避免了多个进程同时访问共享资源而引起的竞争条件。 同时,信号量也可以用于控制多个进程之间的同步和通信。
3.2进程互斥
由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥。
系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。
在进程中涉及到互斥资源的程序段叫临界区。
特性方面:IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核。
4.共享内存的使用示例
makefile
.PHONY:all
all:server client
client:client.c comm.cgcc -o $@ $^
server:server.c comm.cgcc -o $@ $^.PHONY:clean
clean:rm -f client server
comm.h
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define PATHNAME "."
#define PROJ_ID 0x6666int createShm(int size);
int destroyShm(int shmid);
int getShm(int size);#endif
comm.c
static int commShm(int size, int flags)
{key_t _key = ftok(PATHNAME, PROJ_ID);if(_key < 0){perror("ftok");return -1;}int shmid = 0;if( (shmid = shmget(_key, size, flags)) < 0){perror("shmget");return -2;}return shmid;
}int destroyShm(int shmid)
{if(shmctl(shmid, IPC_RMID, NULL) < 0){perror("shmctl");return -1;}return 0;
}int createShm(int size)
{return commShm(size, IPC_CREAT|IPC_EXCL|0666);
}int getShm(int size)
{return commShm(size, IPC_CREAT);
}
server.c
#include "comm.h"
int main()
{int shmid = createShm(4096);char *addr = shmat(shmid, NULL, 0);sleep(2);int i = 0;while(i++<26){printf("client# %s\n", addr);sleep(1);}shmdt(addr);sleep(2);destroyShm(shmid);return 0;
}
client.c
#include "comm.h"
int main()
{int shmid = getShm(4096);sleep(1);char *addr = shmat(shmid, NULL, 0);sleep(2);int i = 0;while(i<26){addr[i] = 'A'+i;i++;addr[i] = 0;sleep(1);}shmdt(addr);sleep(2);return 0;
}
相关文章:
【Linux】进程间通信——system V共享内存、共享内存的概念、共享内存函数、system V消息队列、信号量
文章目录 进程间通信1.system V共享内存1.1共享内存原理1.2共享内存数据结构1.3共享内存函数 2.system V消息队列2.1消息队列原理 3.system V信号量3.1信号量原理3.2进程互斥 4.共享内存的使用示例 进程间通信 1.system V共享内存 1.1共享内存原理 共享内存区是最快的IPC形式…...
【黑马甄选离线数仓day05_核销主题域开发】
1. 指标分类 通过沟通调研,把需求进行分析、抽象和总结,整理成指标列表。指标有原子指标、派生指标、 衍生指标三种类型。 原子指标基于某一业务过程的度量值,是业务定义中不可再拆解的指标,原子指标的核心功能就是对指标…...
使用gin 代理 web网页
问web项目的代理,业界常用的方案是nginx做代理,这个是网上最多资料的。 因为我需要做自己的流量转发,也就是所有访问都要经过我的一个流量分发微服务,这和nginx作用冲突了。如果再加个nginx来做第一层方向代理和网页的静态资源代…...
计算器的模拟实现
计算器的模拟实现 一、实验题目:计算器二:实验目的:三:实验内容与实现1:【实验内容】2:【实验实现】1.计算器界面的实现,如下图所示:2:各项功能的实现,如下图…...
CentOS7搭建smb服务器
安装smb sudo yum install samba samba-client samba-common配置smb vim /etc/samba/smb.conf [shared] path /path/to/shared/folder writable yes browsable yes guest ok yes valid users yourname添加smb用户 sudo useradd youname sudo smbpasswd -a youname然后会…...
openEuler 22.03 LTS x86_64 cephadm 部署ceph 16.2.14 未完成 笔记
环境 准备三台虚拟机 10.47.76.94 node-1 10.47.76.95 node-2 10.47.76.96 node-3 下载cephadm [rootnode-1 ~]# yum install cephadm Last metadata expiration check: 0:11:31 ago on Tue 21 Nov 2023 10:00:20 AM CST. Dependencies resolved. Package …...
Java计算时间差,距结束还有几天几小时几分钟
文章目录 1、写法2、备份3、LocalDate、LocalDateTime、Date、String互转 1、写法 //静态方法,传入年月日时分秒 LocalDateTime startTime LocalDateTime.of(2023, 11, 22, 15, 09, 59); LocalDateTime endTime LocalDateTime.of(2023, 11, 30, 0, 0, 0); //计算…...
【云原生 Prometheus篇】Prometheus的动态服务发现机制与认证配置
目录 一、Prometheus服务发现的方式1.1 基于文件的服务发现1.2 基于consul的服务发现1.3 基于 Kubernetes API 的服务发现1.3.1 简介1.3.2 基于Kurbernetes发现机制的部分配置参数 二、实例一:部署基于文件的服务发现2.1 创建用于服务发现的文件2.2 修改Prometheus的…...
ref详解(C#)
本质上来说 ref 的就是把 C/C 指针的那一套又拿回来了,而且还封装成一套自己的玩法。 我想设计者的初心把 ref 的功能限制得死死的,可能也考虑到 C# 是一门面向业务开发的语言,讲究的是做项目快狠准,性能反而不是第一要素&#x…...
运维高级-day01
shell回顾 1、快速生成版权控制信息,具体的内容自己替换 [root scripts]# cat ~/.vimrc autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()" func SetTitle() if expand("%:e") sh call setline(1,"#!/bin/bash")…...
含分布式电源的配电网可靠性评估matlab程序
微❤关注“电气仔推送”获得资料(专享优惠) 参考文献: 基于仿射最小路法的含分布式电源配电网可靠性分析——熊小萍 主要内容: 通过概率模型和时序模型分别进行建模,实现基于概率模型最小路法的含分布式电源配电网…...
k8s docker总结特殊点
k8s docker总结特殊点 前言一、docker 的驱动。1、cgroup:(Control Groups)2、日志驱动(log driver)3、存储驱动4、网络驱动: 二、k8s中网络插件(常用calico,次flannel)**Flannel:**…...
区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第四套区块链应用后端开发
第四套区块链应用后端开发 环境 : ubuntu20 fisco : 2.8.0 springboot 2.1.1 fisco-java-sdk: 2.7.2 maven 3.8.8 前言 这套后端样题,只涉及调用fisco的系统接口,不涉及此食品溯源项目的业务接口,所以我就直接生成一个springboot项目进行完成此题目。 请提前准备好一…...
《向量数据库指南》——向量数据库Milvus Cloud搭建Excel公式编辑器助手
引言 在日常工作中,Excel是我们经常使用的办公工具,而熟练应用Excel公式对于提高工作效率非常重要。然而,有时候我们会遇到一些复杂的需求,需要用到较为专业的Excel公式,而这正是Excel公式编辑器助手的用武之地。本文将介绍如何利用向量数据库Milvus Cloud搭建GPT大模型和…...
qgis添加arcgis的FeatureServer
左侧浏览器-ArcGIS要素服务器-新建连接 http://sampleserver6.arcgisonline.com/arcgis/rest/services/ 展开-双击即可...
java进阶---多态
多态的概述 什么是多态 同一个对象,在不同时刻表现出来的不同形态 多态的前提 要有继承或实现关系要有方法的重写要有父类引用指向子类对象 多态的具体实现 对象的多态是多态的核心和重点 规则: 一个对象的编译类型与运行类型可以不一致编译类型在定义对象时,就确定了,…...
常用脚本-持续更新(文件重命名、视频抽帧、拆帧、删除冗余文件、yolo2xml、转换图片格式、修改xml)
所有代码位置:Learning-Notebook-Codes/Python/常用脚本 1. 文件重命名 脚本路径:codes/files_rename.py脚本说明:可以自动重命名某个文件夹下指定类型的文件。 修改前文件名称: img1.jpg修改后文件名称: Le0v1n-20231123-X-0001.jpg imp…...
百度文心一言(千帆大模型)聊天API使用指导
开篇不得不吐槽下百度,百度智能云平台首页跳转千帆大模型平台的按钮太多了,不同按钮跳转不同的子页面,不熟悉的,能把人找懵。入口太多,就导致用户不知道从何开始。本文就从一个前端开发人员的角度,教大家快…...
C++知识点总结(7):玩转高精度除法
一、复习高低精度 一个数分为两种类型: 1. 高精度数,即一个长度特别长的数,使用 long long 也无法存储的一类数字。 2. 低精度数,即一个普通的数,可以使用 long long 来存储。 由于高精度除法比较简单,…...
LeetCode算法题解(动态规划,背包问题)|LeetCode1049. 最后一块石头的重量 II、LeetCode494. 目标和
一、LeetCode1049. 最后一块石头的重量 II 题目链接:1049. 最后一块石头的重量 II 题目描述: 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将…...
VL53L0X V2模块的5个‘坑’我帮你踩完了:从静电防护到I2C地址冲突的避坑指南
VL53L0X V2模块实战避坑指南:从静电防护到数据优化的全流程解决方案 第一次拿到VL53L0X V2激光测距模块时,我天真地以为只要接上I2C就能轻松获取精准距离数据——直到项目deadline前三天,模块突然罢工,我才意识到这个看似简单的传…...
猫抓浏览器扩展:三步解锁网页媒体资源下载的终极指南
猫抓浏览器扩展:三步解锁网页媒体资源下载的终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否曾为无法下载网页中的精彩视…...
Qwen2.5-72B-GPTQ-Int4惊艳效果:多轮数学证明生成+中间步骤可追溯展示
Qwen2.5-72B-GPTQ-Int4惊艳效果:多轮数学证明生成中间步骤可追溯展示 1. 引言:当大模型遇上数学推理 如果你尝试过让AI帮你解决数学问题,可能会遇到这样的困扰:它要么直接给出一个最终答案,让你摸不着头脑࿱…...
2006-2023年各省工业机器人安装密度数据
2006-2023年各省工业机器人安装密度数据 1、时间:2006-2023年 2、来源:IFR国际机器人联合会 3、指标:年份、省份代码、省份、所属地域、工业机器人安装密度_台 4、范围:31省 5、说明:根据IRF联盟公布的中国各行业…...
优化EFI引导配置:实现WIN10与UBUNTU20.04双系统无缝切换
1. 双系统引导的痛点与EFI解决方案 每次开机都要狂按F12选择系统?两个系统互相找不到对方?删除一个系统导致另一个也无法启动?这些困扰我多年的双系统问题,终于在一次重装系统时找到了完美解决方案。传统BIOSMBR的方式确实可以实现…...
别再死记硬背K和D了!用Python+OpenCV可视化鱼眼畸变,真正看懂参数含义
用PythonOpenCV动态可视化鱼眼畸变:告别枯燥参数,建立直觉理解 鱼眼镜头拍出来的照片总是带着一种夸张的弧形扭曲——边缘的建筑像是被吸进了黑洞,直线变成了曲线。这种独特的视觉效果在摄影创作中很有魅力,但对计算机视觉算法来说…...
单细胞亚群相关性分析实战:三角热图绘制与corrplot参数详解
1. 单细胞亚群相关性分析的核心价值 第一次拿到单细胞转录组数据时,我盯着那些密密麻麻的基因表达矩阵完全摸不着头脑。直到导师告诉我:"你看这些细胞亚群之间的相关性,就像看社交网络中的朋友圈关系"。这个比喻让我恍然大悟——相…...
AI合规专家:法规GDPR 2.0下的软件测试新使命
一、变革:GDPR 2.0对测试领域的深度重构随着欧盟《通用数据保护条例》升级版(GDPR 2.0)的落地,软件测试从业者正面临角色本质的跃迁。新规在三大维度强化技术约束:算法可解释性强制化:要求AI决策逻辑全程可…...
终极指南:PyPortfolioOpt的MIT许可证完全解析与商业应用实践
终极指南:PyPortfolioOpt的MIT许可证完全解析与商业应用实践 【免费下载链接】PyPortfolioOpt Financial portfolio optimisation in python, including classical efficient frontier, Black-Litterman, Hierarchical Risk Parity 项目地址: https://gitcode.com…...
OCAD应用:四组元连续变焦系统
四组元连续变焦系统是在三组元连续变焦系统的基础上增加了一个变焦组分担系统像面位移,由两个变焦组一个补偿组,再加一个前固定组和后固定组组成。两个变焦组可以接连在一起,第二个变焦组固定不动,也可称为中固定组,虽…...
