Windows进程间通讯(IPC)----共享内存
Windows中同一个EXE文件多次加载过程

Windows中EXE文件加载是基于内存映射文件的。
当EXE文件第一次被加载。
- 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间。
- 系统调用CreateFile打开对应的exe文件。
- 根据PE文件的路径创建文件映射对象,调用CreateFileMapping的参数fdwProtect传入SEC_IMAGE表示映射的文件是一个PE文件,这样系统会按照PE文件头中指定的信息在进程空间指定的地址处预留指定大小的区域,接着调用MapViewOfFileEx将内存映射文件映射到指定的进程地址空间处,因为映射的是一个用SEC_IMAGE属性创建的PE文件的内存映射文件所以系统会根据PE文件头中的信息将PE文件的内存映射文件映射到进程地址空间的各个地址处,并指定此区域的物理存储器来自于磁盘上的EXE文件。
- 这时PE文件并未真正加载到物理内存中,接着会根据PE文件中的输入表中的DLL信息加载DLL。
- 同样会按照DLL文件头的信息在进程空间中指定的地址处预留指定大小的区域,但因为其涉及到重定位所以地址可以改变,且指定预留区域的物理存储器来自于磁盘上的DLL文件和页交换文件。
- 当所有的DLL文件也都预留完区域后,会将EXE文件的第一张代码页加载到内存中,这时CPU运行程序。
- 当CPU运行到内存中不存在的代码页时会发生缺页中断,中断处理程序会将对应的页从磁盘中的EXE文件或DLL文件中加载到内存中。
当EXE文件第二次被加载。
- 因为其会判断此文件已经创建了文件映射对象,所以其不会再次创建文件映射对象了。
- 其直接利用已创建的文件映射对象来调用接着调用MapViewOfFileEx创建新的映射(映射到自己的进程空间中),因为其与第一次运行的程序实例使用的是同一个文件映射对象,因此其与第一次运行的程序实际使用同一块物理内存。
不使用共享内存
因为同一个EXE的多个实例使用的是同一物理内存,当在一个实例的进程空间中更改全局变量或者是局部变量时其他进程也应会做出相应变化。但是实际并没有,也就是全局变量和静态变量并不能在同一个EXE的多个实例进程间共享。原因是因为存在写时复制机制,当尝试更改全局变量或者是静态变量时系统会将物理内存对应的内存页复制到页交换文件中,并修改页交换文件中的内容。此后进程对应的区域就会映射到页交换文件处而不是物理内存处。这样不同的进程映射到不同的页交换文件中所以其不会更改物理内存中的数据,同样无法实现进程间通讯。
使用共享内存
在EXE中使用
使用共享内存实际就是屏蔽写时复制机制,如果指定内存为共享内存则在不同的进程实例中对其更改时,其不会发生写时复制而是直接更改对应物理内存中的数据,所以可以实现进程间通讯。
#pragma data_seg("区块名")
DWORD dwData = 0;
#pragma data_seg()
在源程序中使用如上代码告诉编译器创建一个区块,并且在区块中定义一个变量,此变量必须初始化否则编译器不会将其放在此区块中而是放在其他区块中。
#pragma comment(linker, "/SECTION:区块名,RWS")
在源程序中使用如上代码告诉链接器,更改指定区块的属性,R表示读,W表示写,E表示执行,S表示共享。
在DLL中使用
因为如果一个DLL被多个EXE加载,那么其也只是对此DLL的文件映射对象多建立了几个映射,实际在物理内存中只会存在一块DLL的内存,所以我们可以通过在DLL中使用共享内存而在不同的进程中加载此DLL,利用此DLL的共享内存实现进程间通讯。
#pragma data_seg("区块名")
DWORD dwData = 0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:区块名,RWS")
//导出函数
DWORD GetData()
{
return dwData;
}
void SetData(DWORD dwNum)
{
dwData = dwNum;
}
在DLL中使用共享内存与在EXE中使用共享内存相似,因为DLL被其他进程加载不能直接访问到共享内存中的变量,所以通过对DLL导出函数实现对DLL共享内存的访问。
Windows进程间通讯(IPC)----共享内存的更多相关文章
- QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址:h ...
- High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载
小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...
- Android AIDL 进行进程间通讯(IPC)
编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...
- java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...
- 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...
- Windows进程间通讯(IPC)----内存映射文件
内存映射文件原理 内存映射文件是通过在虚拟地址空间中预留一块区域,然后通过从磁盘中已存在的文件为其调度物理存储器,访问此虚拟内存空间就相当于访问此磁盘文件了. 内存映射文件实现过程 HANDLE hF ...
- Windows进程间通讯(IPC)----消息队列
消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...
- Windows进程间通讯(IPC)----WM_COPYDATA
WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...
- 服务 远程服务 AIDL 进程间通讯 IPC
Activity aidl接口文件 package com.bqt.aidlservice; interface IBinderInterface { /* 更改文件后缀为[.aidl]去掉 ...
随机推荐
- find文本处理(locate)实例学习记录
find文本处理(locate)实例学习记录 (一)按文件名称查找 按照文件名称查找是 find 最常见的用法,需要注意的是,搜索的文件名必须完全匹配,才能找到对应的文件. 1. 查找当前目录下所有 ...
- PTA 二叉树的层次遍历
6-6 二叉树的层次遍历 (6 分) 本题要求实现给定的二叉树的层次遍历. 函数接口定义: void Levelorder(BiTree T); T是二叉树树根指针,Levelorder函数输出给 ...
- 攻防世界 reverse 新手练习区
1.re1 DUTCTF IDA shift+F12 查看字符串 DUTCTF{We1c0met0DUTCTF} 2.game ZSCTF zsctf{T9is_tOpic_1s_v5ry_int7r ...
- 【linux】驱动-4-LED芯片手册分析
目录 前言 4. LED芯片手册分析 4.1 内存管理单元MMU 4.1.1 MMU的功能 4.1.2 TLB的作用 4.2 地址转换函数 4.2.1 ioremap函数 4.2.2 iounmap函 ...
- Android 之 TableLayout 布局详解
TableLayout简介 •简介 Tablelayout 类以行和列的形式对控件进行管理,每一行为一个 TableRow 对象,或一个 View 控件. 当为 TableRow 对象时,可在 Tab ...
- 实现FTP+PAM+MySQL环境,批量配置虚拟用户
实现FTP+PAM+MySQL环境,批量配置虚拟用户 搭建环境: CentOS6.5或CentOS6.7 [root@vhost3 ~]# uname -a Linux vhost3 2.6.32-5 ...
- SpringMVC时间格式和时区解决办法
问题默认情况下在使用spring的@ResponseBody返回json串时,如果有日期类型的数据,会发现在日期会莫名其妙的差8小时比如:2017-12-20 10:16:23.0结果是:2017-1 ...
- BUAA_2021_SE_READING_#2
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 个人阅读作业#2 我在这个课程的目标是 通过课程学习,完成第一个可以称之为"软件"的项目 ...
- position:sticky 粘性定位的几种巧妙应用
背景:position: sticky 又称为粘性定位,粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换.元素根据正常文档流进行 ...
- 全网最清楚的:MySQL的insert buffer和change buffer 串讲
目录 一.前言 二.问题引入 2.1.聚簇索引 2.2.普通索引 三.change buffer存在的意义 四.再看change buffer 五.change buffer 的限制 六.change ...