多个进程范文DLL中的函数/全局变量/数据共享段问题
来源:互联网 发布:excel 数据填表web 编辑:程序博客网 时间:2024/04/29 09:46
转载请标明是引用于 http://blog.csdn.net/chenyujing1234
第一种方法:数据段共享#pragma data_seg
一、
#pragma data_seg()
1,#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的,有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享。
否则多个进程之间无法共享DLL中的全局变量。
2,共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败。
3,你所谓的结果正确是一种错觉。如果你在一个DLL中这么写:
#pragma data_seg("MyData")
int g_Value; // Note that the global is not initialized.
#pragma data_seg()
DLL提供两个接口函数:
int GetValue()
{
return g_Value;
}
void SetValue(int n)
{
g_Value = n;
}
然后启动两个进程A和B,A和B都调用了这个DLL,假如A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值不一定是5,而是一个未定义的值。因为DLL中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。
假如你对g_Value进行了初始化,那么g_Value就一定会被放进MyData段中。换句话说,如果A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值就一定是5!
这就实现了跨进程之间的数据通信!
二、
- #pragma data_seg("flag_data")
- int count=0;
- #pragma data_seg()
- #pragma comment(linker,"/SECTION:flag_data,RWS")
- SETCTIONS
- flag_data READ WRITE SHARED
三、
1、背景
已经将类指针通过共享段共享,在另一进程中是能访问此指针的。
- //----------------------------------------数据定义-------------------------------------------
- #pragma data_seg("flag_data")
- // 保存Gina类的指针
- Gina *g_pWlxContext = NULL;
- #pragma data_seg()
2、出现问题
在另一进程中通过此类指针访问成员访问成员函数是成功的,但通过类指针去访问public属性的数据成员,却显示“Memory UnAccess”
3、解决方法:
3、1 (可行)
将类数据成员单独用全局变量保存起来。
- //----------------------------------------数据定义-------------------------------------------
- #pragma data_seg("flag_data")
- // 保存Gina类的指针
- Gina *g_pWlxContext = NULL;
- HANDLE g_hLsa = NULL;
- #pragma data_seg()
保存起来:
- Gina::Gina(IWinLogon* pWinLogon, HANDLE hLsa)
- : _pWinLogon(pWinLogon), _hLsa(hLsa), _hToken(0), _profilePath(0), _pStatusWindow(0) {
- g_hLsa = _hLsa;
3、2 将整个类作为共享区(可行性未验证)
其他重要内容:
动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。
可见,动态链接库的主要作用就是共享函数库。操作系统提供这样一种机制,保证函数库在系统中只有一份实例。至于DLL中的全局变量,对于每一个进程调用,操作系统会复制一份副本,以避免不同进程之间的干扰。
理论上讲,因为DLL的目的主要在于共享函数库,所提供的函数应尽量具有中立性,不应与应用细节关联太紧密。因为副本的增加要多占用系统资源与处理负担,所以,应该尽量避免在DLL中使用过多的全局变量,尤其是具有大量数据成员和成员函数的C++全局类对象。
DLL是为面向模块和代码复用而设计,但它却时常被用来作软件之间的分层设计。用作分层设计目标的DLL,多进程复用没有太多的意义。实际应用当中也有一种情况,如果一个DLL操控制某个设备在系统中具有唯一性,我们必须要求该DLL考虑不能用于多个进程实例的特性。
然而仅凭操作系统的一些基础性支持,就能做到实例唯一吗?非也,编程者要仔细理解DLL原理与机制,并作大量的练习处理后,才能做到真正的系统实例唯一。
方法之一:在DLL中定义全局变量
DLL定义的全局变量可以被调用进程访问;DLL可以访问调用进程的全局数据。我们可以这样设想,在DLL中定义一标志全局变量,每当进程调用之前,先检查此变量就可以得知是不是已有进程在调用DLL。
然而,DLL中的全局变量会随新进程的应用而拷贝副本。你在A进程中看到的全局变量Flag_XX与你在B进程中看到的Flag_XX其实不是同一样标记。
所以简单的定义全局变量作进程标记,是不能实现进程应用唯一性的判断。
方法二:定义共享数据段
延续方法一的思路。如果能有一种机制,保证多个进程无论启动多少个DLL实例,全局变量不进行副本复制,这个问题就可以解决了。
事实上,操作系统也确实有这个能力,编译器也为此类特殊应用作好的准备:
还有一句话是否正确?
进程间是相互独立的,其实完全可以看成A、B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一份的。
然后在这个基础上,由于代码段是不会被修改的,所以操作系统可以采用copy on write的优化技术,让两个进程共享同一份物理内存。这是属于在不改变系统行为的基础上,为了节省内存,的优化技术。
- 多个进程范文DLL中的函数/全局变量/数据共享段问题
- DLL共享数据段,实现多进程数据共享总结
- DLL共享数据段,实现多进程数据共享总结
- 使用DLL在多个进程间共享全局变量
- 使用DLL在多个进程间共享全局变量
- linux动态链接库全局变量共享问题&DLL共享数据段
- linux动态链接库全局变量共享问题&DLL共享数据段
- linux动态链接库全局变量共享问题&DLL共享数据段
- linux动态链接库全局变量共享问题&DLL共享数据段
- DLL共享数据段
- DLL共享数据段
- DLL中建立进程共享数据段需要注意的语法问题
- DLL动态链接库共享数据段的问题
- dll和exe的共享节------多进程共享dll/exe全局变量
- dll和exe的共享节------多进程共享dll/exe全局变量
- dll和exe的共享节------多进程共享dll/exe全局变量
- dll和exe的共享节------多进程共享dll/exe全局变量
- Dll的各进程之间共享-#pragma data_seg预处理指令用于设置共享数据段
- VC实现将对话框最小化到系统托盘
- dom,sax解析xml
- 阿里校招内推简历筛选的阶段性小结
- 实习总结3-job hunting(西安工作)
- comparable与comparator的区别
- 多个进程范文DLL中的函数/全局变量/数据共享段问题
- Codeforces Round #197 (Div. 2)
- X264帧内预测编码模式
- js 字符串类型转成DATE类型
- Mongodb启动命令mongod参数说明
- netty2修改
- 【分享】Name Disambiguation Data
- object-c学习笔记-1
- 在线全部免费技术视频
仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的(其效果是相同的),
1、第一点:什么是共享数据段?为什么要用共享数据段??它有什么用途??
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg预处理指令用于设置共享数据段。例如:
#pragma data_seg("SharedDataName")
在#pragma data_seg("SharedDataName")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里(以下简称"地址空间")。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。(这项技术又叫code Injection技术,被广泛地应用在了病毒、黑客领域!呵呵^_^)
2、第二点:在具体使用共享数据段时需要注意的一些问题!
Win32 DLLs are mapped into the address space of the calling process. By default, each process using a DLL has its own instance of all the DLLs global and static variables. (注意: 即使是全局变量和静态变量也都不是共享的!) If your DLL needs to share data with other instances of it loaded by other applications, you can use either of the following approaches:
.........