linux 进程间通信_共享内存

目录

一、什么是共享内存?

二、共享内存的特点

优点

缺点

三、使用共享内存的基本函数

 1、创建共享内存shmget()

2、挂接共享内存shmat

3、脱离挂接shmdt

 4、共享内存控制shmctl

 5.查看和删除共享内存

comm.hpp

server.cc 

Client.cc 

Makefile


一、什么是共享内存?

共享内存(Shared Memory)是一种高效的‌进程间通信(IPC)机制‌,允许多个进程直接访问同一块物理内存区域,实现数据的快速交换。它是IPC中速度最快的方式,因为共享内存方式的通信没有中间过程,而管道、消息队列等方式则需要将数据通过中间机制进行转换。

 共享内存的原理如上图所示,主要分为两部(创内存、挂接)

1.进程在物理内存上开辟一块空间,这块空间称为共享内存。

2.不同进程将这块空间挂接到自己的进程地址空间中。

3.进程通过虚拟地址和页表的映射找到共享内存,然后对共享内存进行读写数据。

二、共享内存的特点

优点

  1. 高效性‌:共享内存是所有进程间通信方式中速度最快的,因为所有进程共享同一块内存,访问共享内存区域和访问进程独有的内存区域一样快,并不需要通过系统调用或者其它需要切入内核的过程来完成。
  2. 直接访问‌:避免了数据的各种不必要的复制,数据直接写到内存,不用若干次数据拷贝。
  3. 灵活性‌:不像匿名管道那样要求通信的进程有一定的父子关系。

缺点

  1. 缺乏同步机制‌:系统内核没有对访问共享内存进行同步,必须提供自己的同步措施。例如,在数据被写入之前不允许进程从共享内存中读取信息、不允许两个进程同时向同一个共享内存地址写入数据等。
  2. 生命周期‌:共享内存的生命周期随内核,即如果用户不使用系统调用释放它,直到操作系统关机之前它会一直存在。
  3. 管理复杂性‌:需要额外的同步机制(如信号量、互斥锁)保证数据一致性。

三、使用共享内存的基本函数

 1、创建共享内存shmget()

 int shmget(key_t key, size_t size, int shmflg);
参数key:这个共享内存段名字(和消息队列一样由ftok获取)size:共享内存⼤⼩(自己指定,一般为页的整数倍)shmflg:由九个权限标志构成,它们的⽤法和创建⽂件时使⽤的mode模式标志是⼀样的IPC_CREAT:创建新的共享内存IPC_CREAT|IPC_EXCL|0666:若创建的共享内存存在,报错IPC_NOWAIT:非阻塞0:如果是打开文件,写0
返回值:成功返回⼀个⾮负整数,即该共享内存段的标识码;失败返回-1

2、挂接共享内存shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);
参数shmid: 共享内存标识shmaddr:指定连接的地址(一般默认为NULL,由系统自动分配内存)shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY(连接操作用于只读内存)
返回值:成功返回⼀个指针,指向共享内存第⼀个节;失败返回-1

3、脱离挂接shmdt

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

 4、共享内存控制shmctl

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

 5.查看和删除共享内存

//查看
ipcs -m
//删除
ipcrm -m id(标识)

共享内存使用案例:

分为两个进程,客户端(Client)和服务端(server) 

前提介绍:

.hpp文件的作用与.h文件功能类似

.cc文件等于.cpp文件

comm.hpp

#include <iostream>
#include<stdio.h>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include<string.h>const std::string gpath = "/root/day5_24";
const int gid = 0x6666;
const int gshmsize = 4096;
const int gmode = 0600;
class ShareMemory
{
public:ShareMemory() : _shmid(-1), _ret(nullptr){}~ShareMemory(){}// 创建共享内存int CreateShm(){key_t key = ::ftok(gpath.c_str(), gid);if (key < 0){printf("ftok error\n");return 1;}_shmid = ::shmget(key, gshmsize, IPC_CREAT | IPC_EXCL | gmode);if (_shmid < 0){printf("shmget error\n");return 2;}return _shmid;}// 获得共享内存void GetShm(){key_t key = ::ftok(gpath.c_str(), gid);if (key < 0){printf("ftok error\n");}_shmid = ::shmget(key, gshmsize, IPC_CREAT|gmode);std::cout << "_shmid: " << _shmid << std::endl;if (_shmid < 0){printf("shmget error\n");}}// 挂地址void AttachShm(){_ret = shmat(_shmid, nullptr, 0);std::cout <<  "_shmid: " << _shmid << std::endl;}// 去关联void DetachShm(){int d = shmdt(_ret);if (d == -1){printf("shmdt error\n");return;}printf("shmdt success\n");}// 释放内存void DeleteShm(){shmctl(_shmid, IPC_RMID, nullptr);}void *getadder(){return _ret;}void ShmMeta(){//}private:int _shmid;void *_ret;
};ShareMemory sm;

server.cc 

#include"time.hpp"
#include "Comm.hpp"
using namespace std;int main()
{sm.CreateShm();sm.AttachShm();// 在此处读出while(true){char* image=(char*)sm.getadder();std::cout << image << std::endl;sleep(1);}sm.DetachShm();sm.DeleteShm();return 0;
}

Client.cc 

#include "Comm.hpp"
#include"time.hpp"
int main()
{sm.GetShm();sm.AttachShm();// 在此处写入char*image = (char*)sm.getadder();char i[] = "i am processA";while (true){strcpy(image, i);sleep(1);}sm.DetachShm();return 0;
}

Makefile

SERVER=server
CLIENT=client
CC=g++
SERVER_SRC=Server.cc
Client_SRC=Client.cc.PHONY:all
all:$(SERVER) $(CLIENT)$(SERVER):$(SERVER_SRC)$(CC) -o $@ $^ -std=c++11 -g
$(CLIENT):$(Client_SRC)$(CC) -o $@ $^ -std=c++11 -g.PHONY:clean
clean:rm -f $(SERVER) $(CLIENT)

----------------------------------------------------------------------------------------------------------------------------

本篇介绍到此结束,有问题欢迎给我评论留言。谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 登录实现:JWT 与 Session 全面对比与实战讲解

Spring Boot 登录实现&#xff1a;JWT 与 Session 全面对比与实战讲解 2025.5.21-23:11今天在学习黑马点评时突然发现用的是与苍穹外卖jwt不一样的登录方式-Session&#xff0c;于是就想记录一下这两种方式有什么不同 在实际开发中&#xff0c;登录认证是后端最基础也是最重要…

Vue中的 VueComponent

VueComponent 组件的本质 Vue 组件是一个可复用的 Vue 实例。每个组件本质上就是通过 Vue.extend() 创建的构造函数&#xff0c;或者在 Vue 3 中是由函数式 API&#xff08;Composition API&#xff09;创建的。 // Vue 2 const MyComponent Vue.extend({template: <div…

使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)

在制作教程动图、产品展示、前端 UI 演示等场景中,我们经常需要将视频转换为体积合适且清晰的 GIF 动图。本文将详细介绍如何使用 FFmpeg 工具将视频转为高质量 GIF,包括: ✅ 保留原视频尺寸或自定义缩放✅ 保留原始帧率或自定义帧率✅ 使用调色板优化色彩质量✅ 降低体积同…

【自然语言处理与大模型】大模型Agent四大的组件

大模型Agent是基于大型语言模型构建的智能体&#xff0c;它们能够模拟独立思考过程&#xff0c;灵活调用各类工具&#xff0c;逐步达成预设目标。这类智能体的设计旨在通过感知、思考与行动三者的紧密结合来完成复杂任务。下面将从大模型大脑&#xff08;LLM&#xff09;、规划…

《软件工程》第 11 章 - 结构化软件开发

结构化软件开发是一种传统且经典的软件开发方法&#xff0c;它强调将软件系统分解为多个独立的模块&#xff0c;通过数据流和控制流来描述系统的行为。本章将结合 Java 代码示例、可视化图表&#xff0c;深入讲解面向数据流的分析与设计方法以及实时系统设计的相关内容。 11.1 …

初步尝试AI应用开发平台——Dify的本地部署和应用开发

随着大语言模型LLM和相关应用的流行&#xff0c;在本地部署并构建知识库&#xff0c;结合企业的行业经验或个人的知识积累进行定制化开发&#xff0c;是LLM的一个重点发展方向&#xff0c;在此方向上也涌现出了众多软件框架和工具集&#xff0c;Dify就是其中广受关注的一款&…

高阶数据结构——哈希表的实现

目录 1.概念引入 2.哈希的概念&#xff1a; 2.1 什么叫映射&#xff1f; 2.2 直接定址法 2.3 哈希冲突&#xff08;哈希碰撞&#xff09; 2.4 负载因子 2.5 哈希函数 2.5.1 除法散列法&#xff08;除留余数法&#xff09; 2.5.2 乘法散列法&#xff08;了解&#xff09…

7.安卓逆向2-frida hook技术-介绍

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…

DB-GPT扩展自定义Agent配置说明

简介 文章主要介绍了如何扩展一个自定义Agent&#xff0c;这里是用官方提供的总结摘要的Agent做了个示例&#xff0c;先给大家看下显示效果 代码目录 博主将代码放在core目录了&#xff0c;后续经过对源码的解读感觉放在dbgpt_serve.agent.agents.expand目录下可能更合适&…

Android 架构演进之路:从 MVC 到 MVI,拥抱单向数据流的革命

在移动应用开发的世界里&#xff0c;架构模式的演进从未停歇。从早期的 MVC 到后来的 MVP、MVVM&#xff0c;每一次变革都在尝试解决前一代架构的痛点。而今天&#xff0c;我们将探讨一种全新的架构模式 ——MVI&#xff08;Model-View-Intent&#xff09;&#xff0c;它借鉴了…

【YOLOv8-pose部署至RK3588】模型训练→转换RKNN→开发板部署

已在GitHub开源与本博客同步的YOLOv8_RK3588_object_pose 项目&#xff0c;地址&#xff1a;https://github.com/A7bert777/YOLOv8_RK3588_object_pose 详细使用教程&#xff0c;可参考README.md或参考本博客第六章 模型部署 文章目录 一、项目回顾二、文件梳理三、YOLOv8-pose…

集成30+办公功能的实用工具

软件介绍 本文介绍的软件是千峰办公助手。 软件功能概述与开发目的 千峰办公助手集成了自动任务、系统工具、文件工具、PDF工具、OCR图文识别、文字处理、电子表格七个模块&#xff0c;拥有30余项实用功能。作者开发该软件的目的是解决常见办公痛点&#xff0c;把机械操作交…

IDEA启动报错:Cannot invoke “org.flowable.common.engine.impl.persistence.ent

1.问题 项目启动报错信息 java.lang.NullPointerException: Cannot invoke "org.flowable.common.engine.impl.persistence.ent 2.问题解析 出现这个问题是在项目中集成了Flowable或Activiti工作流&#xff0c;开启自动创建工作流创建的表&#xff0c;因为不同环境的数据…

网络安全--PHP第三天

今天学习文件上传的相关知识 上传的前端页面如下 upload.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

【愚公系列】《生产线数字化设计与仿真》004-颜色分类站仿真(基础概念)

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…

基于 uni-app + <movable-view>拖拽实现的标签排序-适用于微信小程序、H5等多端

在实际业务中&#xff0c;我们经常遇到「标签排序」或「菜单调整」的场景。微信小程序原生的 movable-view 为我们提供了一个简单、高效的拖拽能力&#xff0c;结合 Vue3 uni-app 的组合&#xff0c;我们可以实现一个体验良好的标签管理界面。 核心组件&#xff1a;<movab…

一些较好的学习方法

1、网上有一些非常经典的电路&#xff0c;而且有很多视频博主做了详细的讲解。 2、有一部分拆解的UP主&#xff0c;拆解后会还原该器件的原理图&#xff0c;并一步步做讲解。 3、有两本书&#xff0c;数电、模电&#xff0c;这两本书中的内容很多都值得学习。 5、某宝上卖的…

《1.1_4计算机网络的分类|精讲篇|附X-mind思维导图》

网络相关知识 按使用范围分类 公用网 由电信部门或其他提供通信服务的经营部门组建、管理和控制&#xff0c;向全社会提供服务的网络。 专用网 由某个单位或部门组建、仅供本单位或部门内部使用的网络。 按传输介质分类 有线网络 如&#xff1a;双绞线、同轴电缆、光纤…

Git 和 GitHub 学习指南本地 Git 配置、基础命令、GitHub 上传流程、企业开发中 Git 的使用流程、以及如何将代码部署到生产服务器

Windows 上 Git 安装与配置 下载安装&#xff1a;访问 Git 官方网站下载适用于 Windows 的安装程序。运行安装包时会出现许可协议、安装目录、组件选择等界面&#xff08;如下图&#xff09;。在“Select Components”页面建议勾选 Git Bash Here 等选项&#xff0c;以便在资源…

航空航天领域对滚珠丝杆的精度要求有多高?

航空航天领域对滚珠丝杆的精度要求非常高&#xff0c;尤其是飞行器、火箭和卫星等载具的导航和定位系统都需要高精度的滚珠丝杆&#xff0c;以确保高精度的位置控制和稳定的导航性能。那么&#xff0c;航空航天领域对滚珠丝杆的精度要求有多高&#xff1f; 1、定位精度&#xf…