iis服务器助手广告
返回顶部
首页 > 资讯 > 操作系统 >【Linux】system V 共享内存
  • 704
分享到

【Linux】system V 共享内存

linux服务器运维 2023-08-21 07:08:01 704人浏览 八月长安
摘要

文章目录 system V1. 共享内存原理第一阶段原理第二阶段原理 2. 直接写代码--编写代码进行原理介绍shmget函数ftok函数key值用法 1. 创建key值2. 创建共享内存 获取共享内存3. 将自己和共

system V

system V 是一套标准,独立于文件系统之外的,专门为了通信设计出来的模块
让两个毫不相关的进程看到同一份资源

1. 共享内存原理

第一阶段原理

在这里插入图片描述

进程A和进程B都通过自己的页表映射到物理内存中的特定区域,进而找到该进程匹配的代码和数据
为了让进程A和进程B通信,前提是两者要看到同一份资源
假设在物理内存上开辟一块空间
进程A和进程B在自己的地址空间中都有自己的共享区
想办法把物理内存中新开辟空间 通过页表 映射到 进程A和进程B的共享区中
把地址空间的起始地址返回给用户
进程A和进程B就可以通过起始的虚拟地址,对应页表访问到内存
就完成了让进程A和进程B看到同一份资源,这份资源就被称为共享内存

第二阶段原理

系统中可以用ssh进行通信 ,是不是只能有一对进程使用共享内存呢?
可以,其他进程也可以通信
所以在任何时刻,可能有多个共享内存在被使用
系统中一定会存在很多共享内存同时存在
操作系统要不要整体管理所有的共享内存呢?要
操作性系统如何管理多个共享内存呢?
先描述,在组织
并不是在内存中开辟空间即可,系统为了管理共享内存,构建对应的描述共享内存的结构体对象
共享内存=共享内存的内核数据结构(伪代码:struct shm)+真正开辟的内存空间

2. 直接写代码–编写代码进行原理介绍


打开vscode,创建文件client.cc和server.cc(后缀为cc说明是c++)的文件
创建公共路径 comm.hpp

shmget函数

创建共享路径接口 ,输入 man shmget 查看
在这里插入图片描述

申请一个 系统V的共享内存块
如果创建成功,则会返回共享内存标识符,失败返回-1


size代表申请内存块的大小
shmflg代表 选项
有两个最常用的选项,IPC_CREAT IPC_EXCL
转到定义就可以发现其实这两个都是宏


若单独使用 IPC_CREAT :创建一个共享内存,如果共享内存不存在,就创建之,如果已经存在,就获取已经存在的共享内存并返回
IPC_EXCL不能单独使用 ,一般都要配合 IPC_CREAT
若要将两个选项同时传进去 IPC_CREAT | IPC_EXCL
两个选项同时用: 创建一个共享内存,如果共享内存不存在,就创建之,如果已经存在,则立马出错返回
如果创建成功,对应的共享内存一定是最新的


获取共享内存时,需要有一个key值

ftok函数

输入 man ftok

根据路径和项目id进行算法结合,形成一个冲突概率低的key值
失败就返回-1,成功返回key值

key值用法

假设进程A创建了一个共享内存,但是进程B怎么知道那个共享内存是创建的吗?
就需要借助上述提到的 ftok 函数


在这里插入图片描述

刚开始约定好 A和B用同样的路径字符串和项目id
借助A形成一个key值,将key值放入A创建的共享内存描述结构体中
此时B也形成一个相同的key值,通过寻找key值来找到A所创建的共享内存


pathname 代表 用户自己设定的路径字符串
proj_id 代表 项目id
key值意义为
让创建共享内存的进程可以给新共享内存设置key值
让获取共享内存的进程 通过key值 去找特定匹配的共享内存

1. 创建key值

comm.hpp 公共路径中构建一个函数 GeTKEy 用于返回key值


在这里插入图片描述

构建一个函数 tohex,用于将数转换为十六进制


通过server.cc与client.cc中分别调用Getkey 与tohex函数


两者的返回值key 是相同的,并且返回的都是十六进制数

2. 创建共享内存 获取共享内存

在这里插入图片描述
创建共享内存,调用shmget函数,通过两个选项 若共享内存不存在则创建,若存在则报错
而获取共享内存,调用shmget函数,则返回已有的共享内存


此时运行可执行程序,发现server与client的shmid(共享内存标识符)相同

3. 将自己和共享内存关联起来

输入 man shmat 指令
在这里插入图片描述
at代表 关联
将共享内存和目标值关联起来
返回值为 共享内存的虚拟地址的起始地址
我们不知道应该把共享内存放在虚拟空间的什么地址处,所以shmaddr设为NULL让系统自主去选择
shmflg 可以设置为 SHM_RDONLY 表示当前共享内存是只读的 一般设为0,默认为读写的


4. 将自己和共享内存取消关联

输入 man shmdt 指令
在这里插入图片描述
shmdt代表 虚拟地址
成功返回0,失败返回-1

5. 删除共享内存

创建共享内存的进程已经早就退出了,但是共享内存还存在
确认共享内存存在: ipcs
ipc作为进程间通信的简写
ipc表示资源 s表示有多个资源

在这里插入图片描述
显出来的为ipc通信系统所支持的三种ipc通信策略
Message Queues 消息队列
Shared Memory Segments 共享内存段
Semaphore Arrays 信号量


ipcs - m 查看共享内存段

在这里插入图片描述
perms 代表权限
bytes 代表字节数
nattch 代表 有几个进程和当前进程是关联的

用指令删除

key是在操作系统中使用的,类似于文件的inode编号
shmid 类似于文件的fd
所以删除操作,是在用户层,应该用shmid

在这里插入图片描述


ipcrm -m shmid值 就可以删除共享内存
此时就没有 shmid为0的共享内存 存在了

调用系统调用

输入 man shmctl 指令

在这里插入图片描述
shmid 代表 共享内存描述符 即想对那个共享内存操作
cmd 代表 选项 即想做什么操作
IPC_STAT 获取当前共享内存的属性
IPC_SET 设置共享内存属性
IPC_RMID 标记这个段被释放
buf 代表 共享内存的属性

在comm.hpp下 设置删除共享内存的函数,在server.cc中调用函数 即可删除共享内存

完整代码

makefile

.PHONY:allall:server clientserver:server.ccg++ -o $@ $^client:client.ccg++ -o $@ $^.PHONY:cleanclean:rm -f server client 

如何使两个可执行程序运行,在上一篇文章提到过,点击查看:命名管道


comm.hpp

#ifndef _COMM_HPP_#define _COMM_HPP_#include#include#include#include#include#include#include#include#includeusing namespace std;#define PATHNAME "."//.表示当前路径  路径字符串#define PROJID 0x6666 //项目idconst int gsize=4096;key_t getkey()//用于返回key值{    key_t k=ftok(PATHNAME,PROJID);    if(k==-1)//失败    {       cout<   char buffer[64];   //将x以十六进制的形式传给buffer   snprintf(buffer,sizeof(buffer),"0x%x",x);   return buffer;}static int  createshmhelper(key_t k,int size,int flag)//static修饰只在本文件有效{       int shmid=shmget(k,size,flag);  if(shmid==-1)//创建失败  {    cout<    //带有两个选项 若不存在则创建,若存在则报错    return createshmhelper(k,size,IPC_CREAT |IPC_EXCL);}int getshm(key_t k,int size){    //若有共享内存,则返回已有的共享内存     return createshmhelper(k,size,IPC_CREAT );}char* attachshm(int shmid)//关联{    char*start=(char*)shmat(shmid,NULL,0);//对应类型void* 所以需要强转     return start;}void detachshm(char*start)//取消关联{ int n=shmdt(start); assert(n!=-1); (void)n;}void delshm(int shmid){   int n=shmctl(shmid,IPC_RMID,NULL);   assert(n!=-1);//为-1就删除失败   (void)n;}#endif 

server.cc

#include"comm.hpp"#includeint main(){    //1. 创建key值  key_t k=getkey();//获取key值  cout<<"server:"<

client.cc

#include"comm.hpp"int main(){  key_t k=getkey();//获取key值  cout<<"client key:"<

来源地址:https://blog.csdn.net/qq_62939852/article/details/130188766

--结束END--

本文标题: 【Linux】system V 共享内存

本文链接: https://www.lsjlt.com/news/376780.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【Linux】system V 共享内存
    文章目录 system V1. 共享内存原理第一阶段原理第二阶段原理 2. 直接写代码--编写代码进行原理介绍shmget函数ftok函数key值用法 1. 创建key值2. 创建共享内存 获取共享内存3. 将自己和共...
    99+
    2023-08-21
    linux 服务器 运维
  • 【Linux从入门到精通】通信 | 共享内存(System V)
        本篇文章接着上篇文章通信 | 管道通信(匿名管道 & 命名管道)进行讲解。本篇文章的中点内容是共享内存。 文章目录  一、初识与创建共享内存 1、1 什么是共享内存 1、2 共享内存函数 1、2、1 创建共享内存 ...
    99+
    2023-10-01
    linux 运维 通信 共享内存
  • 【Linux】进程间通信(万字详解)—— 匿名管道 | 命名管道 | System V | 共享内存
    🌈欢迎来到Linux专栏~~进程通信 ...
    99+
    2023-08-22
    linux 服务器 unix
  • Linux之进程间通信(共享内存【mmap实现+系统V】)
    目录共享内存mmap()及其相关的系统调用mmap()munmap()共享内存的使用命令管理共享内存总结共享内存 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,两个不同的进程A、B共享内存的意思就是:同一...
    99+
    2023-03-23
    Linux进程间通信 Linux共享内存 Linux进程
  • Linux中如何共享内存
    这篇文章给大家分享的是有关Linux中如何共享内存的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 共享内存的概念及使用过程1)共享内存的概念共享内存是IPC机制中的一种。共享内存:即允许两个或多个进程共享一个给...
    99+
    2023-06-15
  • linux怎么删除共享内存
    在Linux系统中,可以使用ipcs命令查看当前共享内存的情况。然后可以使用ipcrm命令删除共享内存。1. 使用ipcs命令查看共...
    99+
    2023-08-20
    linux
  • Linux中怎么实现共享内存
    Linux中怎么实现共享内存,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、概念共享内存是被多个进程共享的一部分物理内存,是进程间共享数据的最快的一种方法。&...
    99+
    2023-06-12
  • Linux怎么实现共享内存同步
    本篇内容主要讲解“Linux怎么实现共享内存同步”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux怎么实现共享内存同步”吧!方法一、利用POSIX有名信号灯实现共享内存的同步有名信号量既可...
    99+
    2023-06-28
  • shmget() -- 建立共享内存
    shmget() -- 建立共享内存版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://leezen.blogbus.com/logs/19564086.html #include #include ...
    99+
    2023-06-04
  • Linux如何实现进程间共享内存
    这篇文章主要介绍“Linux如何实现进程间共享内存”,在日常操作中,相信很多人在Linux如何实现进程间共享内存问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux如何实现进程间共享内存”的疑惑有所帮助!...
    99+
    2023-06-27
  • Linux系统共享内存该如何理解
    这篇文章主要为大家分析了Linux系统共享内存该如何理解的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“Linux系统共享内存该如何理解”的知识吧。共享内存在...
    99+
    2023-06-28
  • 云服务器共享内存
    云服务器共享内存的出现可以让用户在不同的云服务器上共享相同的内存空间,而无需为每个应用程序单独购买和管理内存空间。这种技术的优势在于,它可以让用户在多个云服务器上访问相同的数据和文件,并且无需担心数据和文件的安全问题。 使用云服务器共享内...
    99+
    2023-10-27
    内存 服务器
  • Linux进程共享内存的方法是什么
    这篇文章主要讲解了“Linux进程共享内存的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux进程共享内存的方法是什么”吧!共享内存 IPC 原理共享内存进程间通信机制主要用...
    99+
    2023-06-28
  • Linux共享内存实现机制的示例分析
    这篇文章将为大家详细讲解有关Linux共享内存实现机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Linux共享内存实现机制的详解内存共享: 两个不同进程A、B共享内存的意思是,同一块物理内存...
    99+
    2023-06-09
  • Linux下如何共享储存
    这篇文章主要介绍了Linux下如何共享储存,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。192.168.0.1 需要访问192.168.0.2的资源文件。1.检查192.16...
    99+
    2023-06-27
  • Linux中如何共享存储
    这篇文章主要为大家展示了“Linux中如何共享存储”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux中如何共享存储”这篇文章吧。核心概念进程是运行着的程序,每个进程都有着它自己的地址空间,...
    99+
    2023-06-16
  • php共享内存如何设置
    在PHP中,可以使用`shmop`扩展来操作共享内存。以下是设置共享内存的步骤:1. 创建共享内存段:使用`shmop_open()...
    99+
    2023-09-26
    php
  • c++ windows下创建共享内存
    在Windows下,可以使用CreateFileMapping函数来创建共享内存。以下是一个示例代码:```cpp#include ...
    99+
    2023-08-19
    windows
  • PHP入门指南:共享内存
    在Web开发领域中,PHP是一种非常流行的编程语言。它被广泛应用于动态网站的开发,也用于开发各种类型的框架和应用程序。在这个快速发展的行业中,学习PHP编程语言可以为您打开许多机会。在本篇文章中,我们将分享共享内存的相关知识,以帮助初学者掌...
    99+
    2023-05-20
    PHP 入门指南 共享内存
  • python怎么共享内存通信
    在Python中,可以使用多种方式来实现进程间的共享内存通信,下面是一些常用的方法: 使用`multiprocessing`模块中...
    99+
    2023-10-25
    python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作