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)----共享内存的更多相关文章

  1. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  2. High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载

    小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...

  3. Android AIDL 进行进程间通讯(IPC)

    编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...

  4. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

  5. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

  6. Windows进程间通讯(IPC)----内存映射文件

    内存映射文件原理 内存映射文件是通过在虚拟地址空间中预留一块区域,然后通过从磁盘中已存在的文件为其调度物理存储器,访问此虚拟内存空间就相当于访问此磁盘文件了. 内存映射文件实现过程 HANDLE hF ...

  7. Windows进程间通讯(IPC)----消息队列

    消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...

  8. Windows进程间通讯(IPC)----WM_COPYDATA

    WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...

  9. 服务 远程服务 AIDL 进程间通讯 IPC

    Activity aidl接口文件 package com.bqt.aidlservice;  interface IBinderInterface {     /* 更改文件后缀为[.aidl]去掉 ...

随机推荐

  1. 基金 A 类和 C 类、ETF、LOF、QDII 到底是啥?

    ETF 对于初入股市的新手来说,买了一只公司股票容易,想买一个行业的股票就不是很容易了. 比如你要懂得行业里都有谁,每个公司分配多少钱,最主要股票交易最少要交易 1 手也就是 100 股,要是想配置一 ...

  2. GRU算法原理

    一.GRU算法 GRU(Gate Recurrent Unit,循环门单元)是循环神经网络(Recurrent Neural Network, RNN)的一种.和LSTM(Long-Short Ter ...

  3. 【MCU】移植AT32库&FreeRTOS教程

    目录 前言 1. 移植AT库 1.1 移植内核相关文件 1.2 移植芯片型号相关文件 1.3 移植芯片外设驱动库 1.4 移植配置文件及中断回调函数文件 2. 移植FreeRTOS源码 2.1 获取 ...

  4. 使用python的虚拟环境virtualenv

    技术背景 在前面几篇博客中我们介绍了容器的使用(博客1.博客2.博客3.博客4.博客5),容器是一种系统级的隔离方案,更多的强调资源上的隔离.而这里我们要介绍的python的虚拟环境,更加强调的是依赖 ...

  5. 前端er必须知道的Git地址及常用工具地址

    商城篇(找工作必练) 开源商城 推荐指数:5星,掌握了它,可以说,今后工作中的各种需求都不是问题,工作1~2年的也可以学习其中的思路(建议收藏). 这是一个集小程序/公众号/app为一体的商城系统,包 ...

  6. [Fundamental of Power Electronics]-PART I-3.稳态等效电路建模,损耗和效率-3.4 如何获得模型的输入端口

    3.4 如何获得模型的输入端口 Fig 3.16 Buck converter example 让我们尝试使用3.3.3节的步骤来推导图3.16所示的Buck变换器的模型.电感绕组电阻同样由串联电阻\ ...

  7. win10美化,让你的win10独一无二,与众不同!

    2020.06.23 更新 1 原则 美化之前,得先有一个目标对不对,笔者是一个喜欢简单的人,因此美化本着三大原则:简单,干净,整洁. 呃....好像很抽象的样子,上图吧.反正没图没真相. 怎么样,还 ...

  8. 简单的介绍一下Java设计模式:解释器模式

    目录 定义 意图 主要解决问题 优缺点 结构 示例 适用情况 定义 解释器模式是类的行为型模式,给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器,客户端可以使用这个解释器来 ...

  9. json 标准库

    1. 序列化的简单概念 2. json 标准库 2.1 json.dumps() 2.2 json.loads() 2.3 json.dump() 2.4 json.load() 1. 序列化的简单概 ...

  10. 829. Consecutive Numbers Sum

    Given a positive integer N, how many ways can we write it as a sum of consecutive positive integers? ...