转]DLL-多个进程间共享动态链接库的原理

同样这个问题是我在面试总监的时候,总监问我的一个问题,这些天一直 忙活,都没有好好看书了,今天总结一下这个问题?为什么一个进程用完一个动态链接库以后另一个进程还可以继续使用呢?当时回答的很是笼统,只说对了答案的一半,现在就在这里好好总结一下吧!
前面我们已经说过进程间的通信有好几种方式,其实现在我们讲的这种动态链接库也是进程间的通信方式之一。
不管是windows还是Linux操作系统其实所有的操作系统的内涵知识都是一样的。
动态链接库是windows操作系统的基础,其中windows API基本上都是以动态链接库的形式来提供的,通常来说动态链接库是不能够直接运行,也不能直接接收消息的,他们是一些独立的文件(后缀名一般为.dll,当然还有其它的一些后缀名也是可以的),其中包含能被可执行程序或其它DLL调用来完成某项工作的函数,也就是说动态链接库也就是由一些函数组成而已。并且只有在其它模块调用动态链接库中的函数时,动态链接库才发挥作用,在实际的编程中,通常可以完成某种功能的函数放在一个动态链接库中,然后提供给其它函数调用。当这个访问了的动态链接库的进程被加载时,系统会为这个进程分配4GB的私有地址空间(如果是32位机的话),然后系统就会分析这个可执行模块,找到这个可执行模块中将所要调用的DLL,然后系统就负责搜索这些DLL找到这些DLL后便将这些DLL加载到内存中,并为他们分配虚拟内存空间,最后将DLL的页面映射到调用进程的地址空间汇总,DLL的虚拟内存有代码页和数据页,他们被分别映射到进程A的代码页面和数据页面,如果这时进程B也启动了,并且进程B也许要访问该DLL,这时,只需要将该DLL在虚拟内存中的代码页面和数据页面映射到第二个进程的地址空间即可。这也表明了在内存中,只需要存在一份DLL的代码和数据。

多个进程共享 DLL 的同一份代码,很明显这样做可以节省内存空间的。

但是在 Windows 下(Linux中也是一样的),由于系统会为每一个进程分配 4GB 的私有地址空间,

而 DLL 中的代码和数据也只是映射到了这个私有地址空间中,所以这些应用程序之间还是不能够相互影响的,

也就是说多个应用程序虽然是可以共享同一个 DLL 中的相同的代码的,

但是 DLL 为每一个进程保存的数据都是不相同的,

并且每一个进程都为 DLL 使用的全部数据分配了自己的地址空间,

举个最简单的例子,我的 DLL 中有一个函数为 int   Add(int    num1 ,   int    num2)

这个函数的作用是实现 num1  和 num2 相加并返回相加后的结果。

然后我有一个 进程 A  使用了这个 DLL ,并且其调用了函数  Add(10, 20),

然后我还有一个 进程 B 其也使用了这个 DLL ,并且其调用了函数 Add(30, 40),

那么对于 进程 A 中的数据 10 和 20 其实是保存在 进程 A 的私有地址空间中的,

而对于 进程 B 中的数据 30 和 40 则是保存在 进程 B 的私有地址空间中的,

上面这个简单的例子表明如果单单用这种简单的使用动态链接库的方式是不能够实现进程之间的通信的。

如果想利用动态链接库来实现进程间的通信的话,那么有一种方案可以试一试,

即从系统为动态链接库分配的那一块内存(系统需要将动态链接库加载到内存中)下手,

由于在内存中,动态链接库其实只存在一份,

其被所有需要调用该动态链接库中的函数的模块或者简单说是可执行程序所共享,

既然是共享的话,如果我在系统给动态链接库分配的这块内存中保存数据,

那岂不是可以被所有访问该动态链接库的可执行程序所获取或者说设置。

这样的话,我就可以使用 进程 A 来设置好这个共享内存中的数据,

然后 进程 B 就可以读取这个共享内存中的数据了,这不是也可以实现进程间的通信嘛,

这样看来的话,其思路其实和使用剪贴板是一模一样的了。

也是采用一块两个进程共享的内存来作为存放数据的中介。

http://blog.chinaunix.net/uid-26983585-id-3364514.html

时间: 2024-12-11 06:24:02

转]DLL-多个进程间共享动态链接库的原理的相关文章

【转】VC 利用DLL共享区间在进程间共享数据及进程间广播消息

1.http://blog.csdn.net/morewindows/article/details/6702342 在进程间共享数据有很多种方法,剪贴板,映射文件等都可以实现,这里介绍用DLL的共享区间在进程间共享数据,及共享数据有变化时及时的反馈给各相关进程. 一.在DLL中设置共享区间 在DLL中是用数据段来实现共享区间的,有了这个共享区间,各进程可以方便的共享数据. 1.先用#pragma data_seg(Name)设置名为Name的数据段. 2.再用#pragma comment(l

利用内存映射文件在两个进程间共享数据 转

private hMapFile: THandle; MapFilePointer: Pointer; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin hMapFile := CreateFileMapping ( $FFFFFFFF, // 特殊内存映射句柄 nil, page_

windows核心编程之进程间共享数据

有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例. 我们能够在程序中定义一个全局变量.初始化为0.每当程序启动后就加1.当然我们我们能够借助第三方介质来储存这个变量,然后解析. 这样做必须做到先写入后解析.不能实时更新数据.假设不考虑其它储存介质.仅仅是进程中的通信,应该怎么做呢?windows提供了一些可行的方法,以下介绍经常使用的两种. 一.共享数据段 #include "stdafx.h" #include <Windows.h&

android进程间共享简单数据

我们知道,在android中,保存简单的数据最方便的就是使用SharedPreferences,然而,SharedPreferences虽然说也可以设置成进程间共享数据,但是并不可靠(更致命的是,不同级别的应用是无法使用SharedPreferences进行共享的,比如,普通应用无法读取系统应用的SharedPreferences数据). 那如何才能进行简单数据的跨进程共享呢,Settings.System可以很方便的进行跨进程共享数据,使用凡是也很简单: //往系统配置表里添加自定义数据 Se

python 进程间共享数据 (二)

Python中进程间共享数据,除了基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxies来访问.从而达到多进程间数据通信且安全. Manager支持的类型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaph

进程间共享句柄三种方式

windows核心编程第三章中,句柄的共享讲了三种方式 1.在创建句柄的时候,设置可继承,在创建进程时,让子进程继承句柄, 然后通过各种途径(如命令行参数.环境变量.发送消息)让子进程知道即可.2.复制句柄,得先知道目的进程,然后在目标进程中复制句柄, 最后通过各种途径(如发送消息)通知目标进程3.给句柄命名,进程间相互知道名字即可. 第3种在使用Mutex限制只运行一个实例时已使用,前2种没有例子,因此自己写了个实例. 运行后,点击创建进程,会创建一个文件句柄,并置为可继承,然后创建一个环境变

Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析中,我们系统地介绍了Android系统匿名共享内存的实现原理,其中着重介绍了它是如何辅助内存管理系统来有效地管理内存的,在再前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Share

Windows进程间共享内存通信实例

抄抄补补整出来 采用内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保留一段内存区域,把硬盘或页文件上的目标文件映射到这段虚拟内存中.注意:在程序实现中必须考虑各进程之间的同步问题. 在Windows操作系统下,任何一个进程不允许读取.写入或是修改另一个进程的数据(包括变量.对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些进程共享的是物理存储器的同一个页面. 因

C# 进程间共享内存通信方式

从别处看到一篇文章做进程间通信很好使,唯一的问题是,需要注意using的用法,Using有个用法3, using 语句允许程序员指定使用资源的对象应当何时释放资源.using 语句中使用的对象必须实现 IDisposable 接口.此接口提供了 Dispose 方法,该方法将释放此对象的资源. ①可以在 using 语句之中声明对象.     Font font2 = new Font("Arial", 10.0f);     using (font2)     {         /