System V|共享内存基本通信框架搭建|【超详细的代码解释和注释】
前言
那么这里博主先安利一下一些干货满满的专栏啦!
这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!手撕数据结构
https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014.3001.5482
这里是STL源码剖析专栏,这个专栏将会持续更新STL各种容器的模拟实现。算法专栏
https://blog.csdn.net/yu_cblog/category_11464817.html
STL源码剖析
https://blog.csdn.net/yu_cblog/category_11983210.html?spm=1001.2014.3001.5482
什么是System V的共享内存
进程间通信本质:让不同进程看到同一份资源
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
当我们用管道进行进程间通信的时候,我们知道,无论是匿名管道的形式还是命名管道的形式,最后都是需要在磁盘上创建部分空间的。
而共享内存的方案,只需要在内存的级别上创建共享的空间!
至于详细的系统调用接口,博主会在代码的注释中进行解释。
今天博主带着大家把框架搭好,关于通信的具体实现,博主会在下一期进行详细的讲解!
代码下载地址
部分实现原理
shmServer.cc和shmClient.cc代码
注意,仅有这两份代码是不够用的,需要下载代码学习的伙伴要在博主上面提供的链接上下载代码。
这里面是一个完整的项目!
shmServer.cc
#include "comm.hpp"
// 为了让key更好看,和命令行输出的对应起来
// 写一个转换成16进制的函数
std::string TransToHex(key_t k)
{
char buffer[32];
snprintf(buffer, sizeof buffer, "0x%x", k);
return buffer;
}
int main()
{
// 1.创建公共的key值
key_t k = ftok(PATH_NAME, PROJ_ID);
assert(k != -1);
Log("create key done", Debug) << " server key: " << TransToHex(k) << std::endl;
// 2.创建共享内存 -- 建议创建一个全新的共享内存 -- Server是通信的发起者
int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
if (shmid == -1)
{
// 创建失败
perror("shmget");
exit(1);
}
Log("create shm done", Debug) << " shmid: " << shmid << std::endl;
//3.将制定的共享内存,挂接到自己的地址空间
sleep(3);
char* shmaddr = (char*)shmat(shmid,nullptr,0);
Log("attach shm done", Debug) << " shmid: " << shmid << std::endl;
sleep(3);
//我们会看到 挂接数会从0变成1!
// ================= 这里面就是通信的逻辑了!================= //
//...
// ================= 这里面就是通信的逻辑了!================= //
//4.解除挂接
// 将制定的共享内存,从自己的地址空间中去关联
int n = shmdt(shmaddr);
assert(n!=-1);
(void)n;
Log("detach shm done", Debug) << " shmid: " << shmid << std::endl;
sleep(3);
// last. 删除共享内存
//IPC_RMID表示,即便是有进程和当下的shm挂接,依旧删除共享内存
int n = shmctl(shmid, IPC_RMID, nullptr);
assert(n != -1);
(void)n;
Log("delete shm done", Debug) << " shmid: " << shmid << std::endl;
return 0;
}
shmClient.cc
#include "comm.hpp"
int main()
{
key_t k = ftok(PATH_NAME, PROJ_ID);
if(k<0)
{
Log("create key failed", Error) << " client key: " << k << std::endl;
exit(1);
}
Log("create key done", Debug) << " client key: " << k << std::endl;
//获取共享内存
int shmid = shmget(k,SHM_SIZE,IPC_CREAT);
if(shmid<0)
{
Log("create shm success", Error) << " client key: " << k << std::endl;
exit(2);
}
Log("create shm failed", Debug) << " client key: " << k << std::endl;
sleep(5);
//
char* shmaddr = (char*)shmat(shmid,nullptr,0);
if(shmaddr ==nullptr)
{
Log("attach shm failed", Error) << " client key: " << k << std::endl;
exit(3);
}
Log("attach shm success", Debug) << " client key: " << k << std::endl;
sleep(5);
//使用
//去关联
int n = shmdt(shmaddr);
assert(n!=-1);
Log("detach shm success", Debug) << " client key: " << k << std::endl;
sleep(5);
//client要不要chmctl删除呢?不需要!!!
return 0;
}
尾声
看到这里,相信大家对System V通信结构的基本搭建已经有了一定的理解了!如果大家觉得这篇文章对你们有帮助的话,不要吝啬你们的点赞收藏哦!
System V|共享内存基本通信框架搭建|【超详细的代码解释和注释】的更多相关文章
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- UNIX环境高级编程——System V 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- 共享内存之——system V共享内存
System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...
- 阐述linux IPC(五岁以下儿童):system V共享内存
[版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途] system V共享内存和posix ...
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...
- php进程(线程)通信基础--System V共享内存
PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项 System V消息,--enable-sysvmsg System V信号量支持,--enable-sysvsem ...
- Linux system v 共享内存
system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
随机推荐
- 第五届蓝桥杯(2014)C/C++大学A组省赛题解
第一题.猜年龄 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:"我们俩的年龄之积是年龄之和的6倍".小明又补充说:"她们可不是双胞胎,年龄差肯定也不超过8岁 ...
- Element-ui 之 form表单套数组、表单数组套数组的校验rules
https://blog.csdn.net/qq_61553794/article/details/135451461
- 简单的git使用命令
一.Git简介 Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Lin ...
- df -h与df -i的区别
一. df命令详解: linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息 -a 全部文件系统列表 -h ...
- Java21 + SpringBoot3整合Redis,使用Lettuce连接池,推荐连接池参数配置,封装Redis操作
目录 前言 相关技术简介 Redis 实现步骤 引入maven依赖 修改配置文件 定义Redis配置类 定义Redis服务类,封装Redis常用操作 使用Redis服务类 总结 前言 近日心血来潮想做 ...
- [转帖]Jmeter学习笔记(八)——监听器元件之聚合报告
https://www.cnblogs.com/pachongshangdexuebi/p/11507298.html 1.聚合报告添加 聚合报告是常用的监听器之一,添加路径: 点击线程组->添 ...
- 【转帖】SQUID TIME_WAIT值过高引起的服务器被拖慢
https://www.diewufeiyang.com/post/895.html 查看TCP的连接状态值: # netstat -n | awk '/^tcp/ {++S[$NF]} END {f ...
- Nacos集群启动注意事项
简介 Nacos是阿里巴巴开源的一套服务注册发现的应用 使用简单灵活, 是spring Cloud Alibaba的组成部分 现在拆分微服务的部署情况下,极大的需求nacos服务作为支撑 单点情况下存 ...
- vue关于通过下标更改数组的理解
案例1:通过下标更改数组失败 <template> <div> <el-button @click="handlerMe2"> 改变 arr & ...
- 01uni-app的创建运行在不同端上的配置 以及tarBar的配置
uni-app的创建### 01==>创建uni-app的项目非常简单.不需要注意什么注意点哈!! 创建项目的时候 可以参考官网 https://uniapp.dcloud.io/quickst ...