01.虚拟内存

在讲共享内存之前先来聊聊虚拟内存的那些事。

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

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

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

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

02.为什么选择共享内存

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

相对于其他方式,共享内存占用的CPU资源更少且速度更快。不幸的是,共享内存缺少对同步的控制,需要通过其他方式去控制对内存读取同步。

要弥补共享内存的不足,可以通过对写入数据时设置有效位,这样通过对位的检查就能有效控制数据同步。

03.共享内存原理

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

▲图1.1 共享内存原理图

04.Windows下共享内存API函数

4.1 函数头文件

实现共享内存使用的头文件,在Windows环境下使用头文件。

4.2 句柄

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

4.3 CreateFileMappingA函数

4.3.1  函数结构

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);

4.3.2  参数说明

 4.3.3  返回值

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

4.4  OpenFileMappingA函数

4.4.1  函数结构

HANDLE OpenFileMappingA(  DWORD dwDesiredAccess,  BOOL bInheritHandle,  LPCTSTR lpName);/* 示例 */OpenFileMappingA(FILE_MAP_ALL_ACCESS,FALSE,lpName);

4.4.2  参数说明

4.4.3 返回值

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

4.5 MapViewOfFile函数

4.5.1  函数结构​​​​​​​

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

4.5.2  参数说明

4.5.3  返回值

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

4.6  UnmapViewOfFile函数

4.6.1  函数结构​​​​​​​

BOOL UnmapViewOfFile(  LPCVOID lpBaseAddress);/* 示例 */UnmapViewOfFile(lpbase);

4.6.2  参数说明

4.6.3 返回值

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

4.7  CloseHandle函数

4.7.1  函数结构​​​​​​​

BOOL CloseHandle(    HANDLE hObject);/* 示例 */CloseHandle(hmap);

4.7.2  参数说明

4.7.3 返回值

成功返回非零。

05.模拟共享内存

以下例子需要先打开server.exe可执行程序,再打开client.exe可执行程序。本例子中,通过互传的数组p[0]控制server方写(0),或者client方读(1)。

5.1 server.c

#include <Windows.h>#include <stdio.h>#include <stdlib.h>#define lpName "shareMemory"#define FILESIZE 1024LPVOID lpdata = NULL;void main(){    if (lpdata != NULL)    {        printf("ShareMemory exists.\n");    }    HANDLE hmap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, FILESIZE, lpName);    if (hmap == NULL)    {        puts("CreateFileMappingA fail.\n");    system("pause");    } else    {        lpdata = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);        if (lpdata == NULL)        {            printf("MapViewOfFile fail.\n");      system("pause");        }        else        {            int *p = lpdata;            while (1)            {                if (!p[0])                {                    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};                    memcpy(lpdata, a, 40);                }            }        }    }    system("pause");    UnmapViewOfFile(lpdata);    CloseHandle(hmap);    system("pause");}

5.2 client.c​​​​​​​

#include <Windows.h>#include <stdio.h>#include <stdlib.h>#define lpName "shareMemory"void main(){    HANDLE hmapfile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, lpName);    if (hmapfile == NULL)    {        printf("OpenFileMappingA fail.\n");        system("pause");    } else    {        LPVOID lpbase = MapViewOfFile(hmapfile, FILE_MAP_ALL_ACCESS, 0, 0, 0);        if (lpbase == NULL)        {            printf("MapViewOfFile fail.\n");            system("pause");        }else        {            int *p = lpbase;            while (1)            {                if (!p[0])                {                    continue;                } else                {                    for (int i = 1; i < 10; i++)                    {                        printf("%d\n", p[i]);                    }                    int a[1] = {0};                    memcpy(lpbase, a, 4);                }            }        }        UnmapViewOfFile(lpbase);        CloseHandle(hmapfile);        system("pause");    }}

06.SkyEye天目全数字实时仿真软件

迪捷软件自主研发的SkyEye天目全数字实时仿真软件是基于可视化建模的硬件行为级仿真平台,利用拖拽的方式快速搭建任意的虚拟硬件平台,保证虚拟嵌入式系统的可靠性和实时性,进行嵌入式软件的开发和调试。SkyEye目前支持主流的嵌入式硬件平台,可以运行主流的操作系统,此外还能适配国内自主研发的操作系统天脉。通过利用基于LLVM的动态二进制翻译技术,使虚拟处理器在典型的桌面计算机上运行速度可以达到2000MIPS以上。SkyEye支持调用Windows库函数,结合项目实际运行环境,当满足使用共享内存的条件时,通过共享内存完成软件与SkyEye工程之间的数据交互方式让降低项目成本、缩短项目周期成为可能

漫谈Windows共享内存相关推荐

  1. windows共享内存

    在windows编程中避免不了使用共享内存,因为他是进程间通信.文件读取最简单的方式,有书上还说其他进程间通讯机制如管.油槽.WM_COPYDATA底层也是用的共享内存机制.关于使用方法还是请参考MS ...

  2. Windows共享内存解析

    在Windows程序开发过程中,当多个进程之间需要使用同样的数据的时候我们最好的方式就是通过共享内存进行处理(比如:当A进程运行时,进行数据处理,那么此时我想知道数据是不是正确,用B监控,那么A与B之 ...

  3. php windows共享内存,关于php的共享内存的使用和研究之由起

    最近遇到一个场景,服务寻址的时候,需要请求远程的服务,获取一批可用的ip和端口地址及其权重.根据权重和随机算法选择最合适的一个服务地址,进行请求.由于服务地址在短时间之内不会发生变化,因此为了避免无限 ...

  4. php windows共享内存,给PHP开启shmop扩展实现共享内存

    这篇文章主要介绍了关于给PHP开启shmop扩展实现共享内存,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 在项目开发中,想要实现PHP多个进程之间共享数据的功能,让客户端连接能够共享 ...

  5. Windows共享内存详解

    文章目录 前言 一.什么是共享内存? 二.使用方法 三.具体使用 四.注意事项 前言 一般来说,进程都处于不同的空间内,如果进程间想要通信,就需要用到其它方法,例如共享内存.管道.邮槽.本地回环网络. ...

  6. Boost:shared_memory_object --- 共享内存

    什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时, ...

  7. boost库中共享内存的使用

    什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时, ...

  8. Windows Mobile使用Shared Memory(共享内存)进行IPC(进程间通信)的开发

    背景 在Unix-like系统进行IPC(Inter-process communication)通信,Shared memory是效率最高的,我称之为IPC的王中王. 简介 本文讲述在Windows ...

  9. java 内存映射文件进程间通讯_[转]Windows环境下利用“共享内存”实现进程间通信的C/C++代码---利用CreateFileMapping和MapViewOfFile...

    进程间的通信方式有很多种, 上次我们说了最傻瓜的"共享外存/文件"的方法. 那么, 在本文中, 我们即将学习"共享内存"的方式实现进程间的通信, 这是IPC最快 ...

最新文章

  1. python入门指南 许半仙txt百度云-《婚前教育》TXT全本 百度云网盘下载 by鱼一三...
  2. 暴汗,今天遇到个奇事
  3. oracle存储过程和job
  4. java可存储100个整数的数组_定义一个一维整数数组,其中储存1000个1至100以内的整数,并统计出整数出现的次数(Java写出来)...
  5. Eclipse 安装Gradle插件
  6. C语言试题三十一之判断字符串是否为回文?若是则函数返回1,主函数中输出yes,否则返回0,主函数中输出no。回文是指顺读和倒读都是一样的字符串。
  7. 关于Unity实现AR功能(五)摄像头转换与闪光灯开关控制
  8. SSM框架Spring+SpringMVC+MyBatis——详细整合教程
  9. 论文相关------如何在论文写作中使用拉丁文简写
  10. 2020 CSP-S第二轮认证一等奖获奖名单
  11. 向量运算(点积,叉积)
  12. The current branch master has no upstream branch.的解决
  13. TIA博途_数据的保持型与初始化的具体方法和相关问题汇总
  14. android来电没有弹窗
  15. 四种方法解决:Windows10下使用SVN文件夹不显示小绿勾
  16. c++之十进制转二进制
  17. liunx下设置自动完成任务(每周六晚一点整,系统自动把/home目录文件下到所有文件做一个备份,备份到/var/backups/home.tar.gz))
  18. 浏览器推荐-以Windows操作系统为例
  19. 微信小程序版本更新后提示用户更新
  20. 一键安装ghost轻博客

热门文章

  1. C语言137页答案,综合化学实验答案题库(137页)-原创力文档
  2. mysqldump全量恢复_mysql全量备份和快速恢复的方法整理
  3. python 选择文件对话框插件_[ PyQt入门教程 ] PyQt5基本控件使用:消息弹出、用户输入、文件/目录选择对话框...
  4. 5-11attention网络结构
  5. 用python做自动化测试仪器_使用python进行windows自动化测试(1)
  6. vpr文件转换flac_有什么简单方法将flac无损转换mp3
  7. 选项在哪_心理测试:4种高跟鞋,比较喜欢哪一种?测试出你对物的欣赏面
  8. 主表的引用字段中找不到唯一的索引_不用找了,大厂在用的分库分表方案,都在这里!...
  9. mysql 触发器 所有表_MySQL触发器可以与多个表或所有表相关联吗?
  10. python Box-Cox数据变化与逆变化