每日Bug:(2)共享内存

对于整个系统而言,主存与CPU的资源都是有限的,随着打开进程数量的增加,若是将所有进程运行所需的代码/数据/栈/共享库都存放在主存中,那么开启一部分进程就可以将主存占用完。

虚拟内存就是解决以上问题的方法,使用虚拟内存不用将进程全部内容加载到主存上(局部性立了大功——进程在某段时间只需要用到部分代码及其数据),虚拟内存与主存通过不断的数据交换,只需要占用满足程序运行最小空间的内存即可完成程序运行。

不光如此,虚拟内存为程序分配同样的空间便于管理(意味着进程自认为占用了整个内存)。同时,虚拟内存为每个进程增添地址空间的安全性,保护其地址空间不被其他进程所破坏。

正如上述所说虚拟内存的优点,共享内存基于虚拟内存通过内存映射的方式应运而生。

数据交互的方式有很多种且各有千秋,比如匿名管道、有名管道、信号、消息队列。为什么选择共享内存?同一台主机下多进程之间通信,其他方式需要通过内核进行四次数据交互才能完成一次通信,但共享内存只需要两次且不经过内核。

相对于其他方式,共享内存占用的CPU资源更少且速度更快。不幸的是,共享内存缺少对同步的控制,需要通过其他方式去控制对内存读取同步。弥补共享内存的不足,可以通过对写入数据时设置有效位,这样通过对位的检查就能有效控制数据同步。

原理:

在Windows下每个进程都存在一张页表,通过MMU将进程的虚拟地址映射到真实的物理内存。基于虚拟内存的使用原理,共享内存在此基础上通过函数指定方式将多个进程的虚拟内存同时指向同一片共享内存地址空间,并通过函数参数控制进程的访问权限等参数,从而完成多个进程间的数据通信。

Windows下共享内存API函数

句柄

句柄作为共享内存机制的重要概念,日常编程中不会经常用到。将句柄具象化可以理解为“刀柄”,操作系统“手握”句柄指向一块区域,区域中存有各个对象的地址、属性等信息,操作系统通过“刀柄”可以顺藤摸瓜找到对象所在以及其他信息。

在windows编程中,有个概念是句柄,句柄指向资源(一切可以利用的物理的逻辑的资源),其中文件操作,可以将文件映射到内存,此处的文件是广义的文件,可以指内存对象,邮件槽等。

在windows中创建一个指向文件的虚拟内存,然后多个进程创建各个进程对这块内存的映射,通过访问各个进程的映射内存对这块虚拟内存进行访问,是共享内存实现的原理。

CreateFileMappingA函数

HANDLE CreateFileMappingA(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
);HANDLE hmap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, FILESIZE, lpName);

返回值:创建成功返回文件句柄,创建失败则返回NULL。

OpenFileMappingA函数

HANDLE OpenFileMappingA(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);OpenFileMappingA(FILE_MAP_ALL_ACCESS,FALSE,lpName);

返回值:成功返回文件句柄,失败则返回NULL。

MapViewOfFile函数

LPVOID MapViewOfFile(
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
);MapViewOfFile(hmapfile,FILE_MAP_ALL_ACCESS,0,0,0);

返回值:成功返回映射视图起始地址,失败返回NULL。

UnmapViewOfFile函数

BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);UnmapViewOfFile(lpbase);

返回值:成功返回非零,失败返回零。

CloseHandle函数

BOOL CloseHandle(HANDLE hObject);CloseHandle(hmap);

返回值:成功返回非零。

Handle

Handle的用途就是实现线程之间的通信,例如:当子线程做一个耗时的操作的时候,我们并不知道他什么时候做完,做完了也不知道,那么,我们是不是需要一个东西来通知我们,让我们知道呀,所以说,也就有了Handle的来源,没有Handle这个东西,对我们来说,非常的麻烦。句柄(Handle)是一个用于标识和管理系统资源的抽象标识符。不同类型的句柄用于管理不同类型的资源。

演示:

1、写入端:

#include<iostream>
#include<windows.h>
using namespace std;int main() {unsigned long buffsize = 100;// 创建或打开一个命名的内存映射文件对象HANDLE m_handle= CreateFileMapping(INVALID_HANDLE_VALUE, // 使用系统分页文件: INVALID_HANDLE_VALUE表示共享未与文件关联的内存NULL,  // 默认安全性,决定返回的句柄是否可以被子进程继承,如果为 NULL,则不能。PAGE_READWRITE,  // 可读写权限,当取 PAGE_READWRITE 时,表示对文件映射对象有可读可写的权限0,  // 最大对象大小(高位)buffsize, // 最大对象大小(低位)L"SharedMemory");if (m_handle == NULL) {cout << "CreateFileMapping failed: " << GetLastError() << endl;return 1;}// 映射缓冲区视图,如果函数成功,则返回值是映射视图的起始地址。// 将文件映射对象映射进调用的进程的虚拟地址空间LPVOID pVoid = MapViewOfFile(m_handle, // 映射对象句柄FILE_MAP_ALL_ACCESS, // 可读写许可0,//表示文件映射起始偏移的高32位0,//表示文件映射起始偏移的低32位buffsize// 映射大小,文件中要映射的字节数。0表示映射整个文件映射对象,单位是字节。);if (pVoid == NULL) {cout << "MapViewOfFile failed" << GetLastError << endl;CloseHandle(m_handle);return 1;}HANDLE Semaphore_write = CreateSemaphore(NULL, 1, 1 ,L"MySemaphore");if (Semaphore_write == NULL) {cout << "CreateSemaphore failed: " << GetLastError() << endl;UnmapViewOfFile(pVoid);CloseHandle(m_handle);return 1;}int num=1;while (true) {WaitForSingleObject(Semaphore_write,INFINITE);memcpy(pVoid,&num, sizeof(num));FlushViewOfFile(pVoid, buffsize); // 确保写入生效cout << "write:num=" << num << endl;num++;ReleaseSemaphore(Semaphore_write, 1, NULL);Sleep(1000);}UnmapViewOfFile(pVoid); //取消文件映射后,进程中该部分的地址会被释放(可以理解成free操作),然后该部分的内存可以被用于其他分配。CloseHandle(Semaphore_write);CloseHandle(m_handle);
}

2、读取端:

#include<iostream>
#include<windows.h>
using namespace std;int main() {unsigned long buffsize = 100;HANDLE m_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE, // 继承标志L"SharedMemory");if (m_handle == NULL) {cout << "CreateFileMapping failed: " << GetLastError() << endl;return 1;}LPVOID pVoid = MapViewOfFile(m_handle,FILE_MAP_ALL_ACCESS,0,0,buffsize);if (pVoid == NULL) {cout << "MapViewOfFile failed" << GetLastError << endl;CloseHandle(m_handle);return 1;}HANDLE Semaphore_read = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, // 需要这两个权限FALSE,                                // 不继承L"MySemaphore"                     // 必须和写入程序一致);if (Semaphore_read == NULL) {cout << "OpenSemaphore failed: " << GetLastError() << endl;UnmapViewOfFile(pVoid);CloseHandle(m_handle);return 1;}int read_num = 0;while (true) {WaitForSingleObject(Semaphore_read, INFINITE);memcpy(&read_num, pVoid, sizeof(read_num));cout << "read num=" << read_num << endl;ReleaseSemaphore(Semaphore_read, 1, NULL);Sleep(1000);}UnmapViewOfFile(pVoid);CloseHandle(m_handle);CloseHandle(Semaphore_read);return 0;
}

3、运行结果:

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

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

相关文章

C语言Makefile编写与使用指南

Makefile 详细指南&#xff1a;编写与使用 Makefile 是 C/C 项目中常用的自动化构建工具&#xff0c;它定义了项目的编译规则和依赖关系。下面我将详细介绍 Makefile 的编写和使用方法。 一、Makefile 基础 1. 基本结构 一个典型的 Makefile 包含以下部分&#xff1a; mak…

Centos离线安装Docker(无坑版)

1、下载并上传docker离线安装包 官方地址&#xff1a;安装包下载 2、上传到离线安装的服务器解压 tar -zxvf docker-28.1.1.tgz#拷贝解压二进制文件到相关目录 cp docker/* /usr/bin/ 3、创建docker启动文件 cat << EOF > /usr/lib/systemd/system/docker.servic…

OceanBase数据库-学习笔记4-租户

租户 租户偏向于资源层面的逻辑概念&#xff0c;是在物理节点上划分的资源单元&#xff0c;可以指定其资源规格&#xff0c;包括 CPU、内存、日志盘空间、IOPS 等。 租户类似于传统数据库的数据库实例&#xff0c;租户通过资源池与资源关联&#xff0c;从而独占一定的资源配额…

UNIAPP项目记录

一、通过 vue-cli 创建 uni-app 项目 创建 vue3 项目 创建以 javascript 开发的工程&#xff08;如命令行创建失败&#xff0c;请直接访问 gitee 下载模板&#xff09; npx degit dcloudio/uni-preset-vue#vite my-vue3-project复制代码 npx degit dcloudio/uni-preset-vue#vit…

华为发布全球首个L3商用智驾ADS4.0

2024年10月2024世界智能网联汽车大会上&#xff0c;余承东讲到&#xff1a;“华为ADS 4.0将于2025年推出高速L3级自动驾驶商用及城区L3级自动驾驶试点&#xff0c;希望加快L3级自动驾驶标准的进程&#xff0c;推动L3级自动驾驶技术的普及。” 世界智能网联汽车大会演讲PPT 所以…

【Python学习路线】零基础到项目实战

目录 &#x1f31f; 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 &#x1f9e0; 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 &#x1f4bb; 二、实战演示环境配置要求核心代码实现运行结果验证 ⚡ 三、性能对比测试方法论量化数据对比…

解决redis序列号和反序列化问题

最近遇到了一个问题,将 List<Map<String, Object>> 类型数据以list形式存入到redis之后,发现取出来时数据格式完全不对,根据报错信息发现是反序列化问题,遇到类似问题,主要有两种解决方案1.使用序列号工具 例如&#xff0c;Java中常用的序列化工具有Jackson、Gso…

Android学习总结之设计场景题

设计图片请求框架的缓存模块 核心目标是通过分层缓存策略&#xff08;内存缓存 磁盘缓存&#xff09;提升图片加载效率&#xff0c;同时兼顾内存占用和存储性能。以下是针对 Android 面试官的回答思路&#xff0c;结合代码注释说明关键设计点&#xff1a; 一、缓存架构设计&…

Webug3.0通关笔记14 第十四关:存储型XSS

目录 第十四关:存储型XSS 1.打开靶场 2.源码分析 3.渗透实战 第十四关:存储型XSS 本文通过《webug3靶场第十四关 存储型XSS》来进行存储型XSS关卡的渗透实战。 存储型 XSS&#xff08;Stored Cross - Site Scripting&#xff09;&#xff0c;也被称为持久型 XSS&#xff…

Java父类、子类实例初始化顺序详解

1、完整的初始化顺序&#xff08;含继承&#xff09; 1、父类的静态初始化 父类静态变量默认值 → 父类静态变量显式赋值 父类静态代码块&#xff08;按代码顺序执行&#xff09;。 2、子类的静态初始化 子类静态变量默认值 → 子类静态变量显式赋值 子类静态代码块&…

13.组合模式:思考与解读

原文地址:组合模式&#xff1a;思考与解读 更多内容请关注&#xff1a;7.深入思考与解读设计模式 引言 在软件开发中&#xff0c;是否曾经遇到过这样一种情况&#xff1a;你有一个对象&#xff0c;它本身很简单&#xff0c;但是它包含了其他类似的对象。随着系统变得越来越复…

OpenCV实战教程 第一部分:基础入门

第一部分&#xff1a;基础入门 1. OpenCV简介 什么是OpenCV及其应用领域 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库&#xff0c;于1999年由Intel公司发起&#xff0c;现在由非营利组织OpenCV.org维护。Ope…

虚幻商城 Quixel 免费资产自动化入库(2025年版)

文章目录 一、背景二、问题讲解1. Quixel 免费资产是否还能一键入库?2. 是不是使用了一键入库功能 Quixel 的所有资产就能入库了?3. 一键入库会入库哪些资产?三、实现效果展示四、实现自动化入库五、常见问题1. 出现401报错2. 出现429报错3. 入库过于缓慢4. 入库 0 个资产一…

uni-app - 小程序使用高德地图完整版

文章目录 🍉功能描述🍉效果🍉开发环境🍉代码部分🍉功能描述 页面自动通过定位获取用户位置并展示周边POI数据,同时支持关键词输入实时联想推荐关联地点信息, 实现精准智能的地点发现与检索功能。 🍉效果 🍉开发环境 unibest2.5.4nodev18.20.5pnpm9.14.2wot-des…

牛客:AB4 逆波兰表达式求值

链接&#xff1a;逆波兰表达式求值_牛客题霸_牛客网 题解&#xff1a; 利用栈&#xff0c;遍历字符串数组&#xff0c;遇到运算数则入栈&#xff0c;遇到运算符则取出栈顶两个运算数进行运算&#xff0c;并将运算结果入栈。 class Solution { public:/*** 代码中的类名、方法…

Ant(Ubuntu 18.04.6 LTS)安装笔记

一、前言 本文与【MySQL 8&#xff08;Ubuntu 18.04.6 LTS&#xff09;安装笔记】同批次&#xff1a;先搭建数据库&#xff0c;再安装JDK&#xff0c;后面肯定就是部署Web应用。其中Web应用的部署使用 Ant 方式&#xff0c;善始善终&#xff0c;特以笔记。 二、准备 &#xf…

ultralytics 目标检测 混淆矩阵 背景图像 没被记录

修改 utils/metrics.py ConfusionMatrix def process_batch(self, detections, gt_bboxes, gt_cls):"""Update confusion matrix for object detection task.Args:detections (Array[N, 6] | Array[N, 7]): Detected bounding boxes and their associated inf…

iview 如何设置sider宽度

iview layout组件中&#xff0c;sider设置了默认宽度和最大宽度&#xff0c;在css样式文件中修改无效&#xff0c;原因是iview默认样式设置在了element.style中&#xff0c;只能通过行内样式修改 样式如下&#xff1a; image.png image.png 修改方式&#xff1a; 1.官方文档中写…

go-zero(十七)结合DTM :实现分布式事务

1. 基础概念介绍 1.1 什么是分布式事务 在微服务架构中&#xff0c;一个业务操作常常需要调用多个服务来完成。例如&#xff0c;在电商系统中下单时&#xff0c;需要同时操作订单服务和库存服务。这种跨服务的操作就需要分布式事务来保证数据一致性。 分布式事务面临以下挑战…

2025 简易Scrum指南(简体中文版)

Scrum是一个轻量级的、以团队为中心的框架&#xff0c;用于解决复杂的问题并创造价值。Scrum有意保持非完整性&#xff0c;Scrum的设计初衷旨在依靠使用者的集体智慧来不断演进构建。 Scrum建立在实验主义和精益思想的基础上&#xff0c;它赋能团队灵活巧妙地工作&#xff0c;…