精华内容
下载资源
问答
  • 不同进程加载同一个动态库时
    更多相关内容
  • 个进程调用同一个动态库

    创作人QQ:851301776,邮箱:lfr890207@163.com,欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!

    个人座右铭:
    1.没有横空出世,只要厚积一定发。
    2.你可以学历不高,你可以不上学,但你不能不学习

    一、问题

              假如动态库中有一个全局变量,动态库所提供的调用函数,本质是操作这个全局变量。如果多个进程同时调用调用这个动态库,可不可以,是不是安全的。

            我回答的是:可以。

            接下来就会问:为什么? 

            然后我懵逼了。

            唉,被问到几次,一直没实际测试做总结,今天自己总结一下,希望自己可以真正意义上的理解。

    二、实战

    1.做一个动态库(libhello.so)

    (1)头文件内容

    #ifndef     __HELLO_H__
    #define     __HELLO_H__
    
    int hello_add();
    
    #endif 
    

    (2)源文件中内容

    #include <stdio.h>
    #include "hello.h"
    
    int num = 0;
    
    int hello_add()
    {
        printf("num=%d\n", num++);
        return 0;
    }
    

    2.写两个进程

    (1)进程1内容

    #include <stdio.h>
    
    #include "./so/hello.h"
    
    int main(void)
    {
        int i = 100;
        while(i--)
        {
            sleep(1);
            printf("%s %d %s\n", __FILE__, __LINE__, __func__);
            hello_add();
        }
    }

    (2)进程2内容

    #include <stdio.h>
    
    #include "../so/hello.h"
    
    int main(void)
    {
        int i = 100;
        while(i--)
        {
            sleep(1);
            printf("%s %d %s\n", __FILE__, __LINE__, __func__);
            hello_add();
        }
    }

    3.打印结果

     4.结论

            多个进程同时访问同一个动态库,操作的是全局变量,互相不影响。

     三、原因

     解释:dll是windows中的动态库

            当这个访问了的动态链接库的进程被加载时,系统会为这个进程分配4GB的私有地址空间(如果是32位机的话),然后系统就会分析这个可执行模块,找到这个可执行模块中将所要调用的DLL,然后系统就负责搜索这些DLL找到这些DLL后便将这些DLL加载到内存中,并为他们分配虚拟内存空间,最后将DLL的页面映射到调用进程的地址空间汇总,DLL的虚拟内存有代码页和数据页,他们被分别映射到进程A的代码页面和数据页面,如果这时进程B也启动了,并且进程B也许要访问该DLL,这时,只需要将该DLL在虚拟内存中的代码页面和数据页面映射到第二个进程的地址空间即可。其中不变的代码段和数据段只有一份拷贝,会变的内容是各个进程自己拷贝的那一份。

    四、动态库和静态库的区别 

    静态库:使用静态库链接生成的可执行文件,是将静态库中被使用到的模块复制到可执行文件中.
    所以,这样的可执行文件不再依赖于静态库文件

    动态库:代码加载到内存执行的时候,才发生的链接.延迟链接,也叫按需加载  ,程序执行的过程中,需要使用到动态库的时候,再向系统申请将动态库加载到内存中。

    五、进程的内存管理

    每个进程都有如下几个段:

    (1)代码段:只读可执行

    (2)数据段:可读可写,不可执行,主要存放以初始化的全局变量和static声明的变量

    (3)栈段:可读可写,不可执行,一个栈段包含多个栈帧.每个函数都有自己对应的栈帧.函数执行期间,函数的栈帧存在,函数调用结束,函数对应的栈帧也就消失了.栈段的生命周期是整个进程   进程的生命周期。

    (4)堆段:可读可写,不可执行

    (5)BSS段:可读,主要存放未初始化的全局变量和初始化为0的全局变量

    展开全文
  • 我猜,同一个进程加载同一个动态库两次,用的其实是同一份内存空间。下面直接根据代码看结果。 // 下面的测试动态库Test.dll的代码,就一个头文件dll_global.h和一个main.cpp. #ifndef DLL_GLOBAL_H #define DLL_...

    我猜,同一个进程加载同一个动态库两次,用的其实是同一份内存空间。下面直接根据代码看结果。

    // 下面的测试动态库Test.dll的代码,就一个头文件dll_global.h和一个main.cpp.
    
    #ifndef DLL_GLOBAL_H
    #define DLL_GLOBAL_H
    
    #ifdef __cplusplus
    #define D_EXTERN_C extern "C"
    #else
    #define D_EXTERN_C
    #endif
    
    #ifdef __SHARE_EXPORT
    #define D_SHARE_EXPORT D_DECL_EXPORT
    #else
    #define D_SHARE_EXPORT D_DECL_IMPORT
    #endif
    
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
    #define D_CALLTYPE __stdcall
    #define D_DECL_EXPORT __declspec(dllexport)
    #define D_DECL_IMPORT
    #else
    #define __stdcall
    #define D_CALLTYPE
    #define D_DECL_EXPORT __attribute__((visibility("default")))
    #define D_DECL_IMPORT __attribute__((visibility("default")))
    #endif
    
    D_EXTERN_C D_SHARE_EXPORT void D_CALLTYPE Dll_SetValue(int value);
    D_EXTERN_C D_SHARE_EXPORT int D_CALLTYPE Dll_GetValue();
    
    #endif // DLL_GLOBAL_H
    
    ============================================================================ 
    
    #include "dll_global.h"
    
    int g_value = 0;
    
    //---------------------------------------------------------------------------
    void Dll_SetValue(int value)
    {
        g_value = value;
    }
    //---------------------------------------------------------------------------
    int Dll_GetValue()
    {
        return g_value;
    }
    //---------------------------------------------------------------------------
    
    // 下面是测试工具的代码 
    #include <QCoreApplication>
    #include <QString>
    #include <QLibrary>
    #include <QDebug>
    
    typedef int (_stdcall *Dll_SetValue)(int value);
    typedef int (_stdcall *Dll_GetValue)();
    
    int loadDll_SameDllTwice()
    {
        qDebug() << "===========loadDll_SameDllTwice=========";
        Dll_SetValue pDll_SetValue1{nullptr};
        Dll_GetValue pDll_GetValue1{nullptr};
        {
            QLibrary qLib(QString("./TestDll.dll"));
            if(false == qLib.load())
                return -1;
    
            pDll_SetValue1 = (Dll_SetValue)qLib.resolve("Dll_SetValue");
            if(nullptr == pDll_SetValue1)
                return -2;
    
            pDll_GetValue1 = (Dll_GetValue)qLib.resolve("Dll_GetValue");
            if(nullptr == pDll_GetValue1)
                return -3;
        }
    
        Dll_SetValue pDll_SetValue2{nullptr};
        Dll_GetValue pDll_GetValue2{nullptr};
        {
            QLibrary qLib(QString("./TestDll.dll"));
            if(false == qLib.load())
                return -1;
    
            pDll_SetValue2 = (Dll_SetValue)qLib.resolve("Dll_SetValue");
            if(nullptr == pDll_SetValue2)
                return -2;
    
            pDll_GetValue2 = (Dll_GetValue)qLib.resolve("Dll_GetValue");
            if(nullptr == pDll_GetValue2)
                return -3;
        }
    
        qDebug() << "pDll_SetValue1: " << &pDll_SetValue1;
        qDebug() << "pDll_SetValue2: " << &pDll_SetValue2;
        qDebug() << "pDll_GetValue1: " << &pDll_GetValue1;
        qDebug() << "pDll_GetValue2: " << &pDll_GetValue2;
    
        pDll_SetValue1(123);
        qDebug() << "pDll_SetValue1(123), pDll_GetValue2=" << pDll_GetValue2() << endl;
    
        return 0;
    }
    
    int loadDll_DiffDllOnce()
    {
        qDebug() << "===========loadDll_DiffDllOnce=========";
        Dll_SetValue pDll_SetValue1{nullptr};
        Dll_GetValue pDll_GetValue1{nullptr};
        {
            QLibrary qLib(QString("./TestDll1.dll"));
            if(false == qLib.load())
                return -1;
    
            pDll_SetValue1 = (Dll_SetValue)qLib.resolve("Dll_SetValue");
            if(nullptr == pDll_SetValue1)
                return -2;
    
            pDll_GetValue1 = (Dll_GetValue)qLib.resolve("Dll_GetValue");
            if(nullptr == pDll_GetValue1)
                return -3;
        }
    
        Dll_SetValue pDll_SetValue2{nullptr};
        Dll_GetValue pDll_GetValue2{nullptr};
        {
            QLibrary qLib(QString("./TestDll2.dll"));
            if(false == qLib.load())
                return -1;
    
            pDll_SetValue2 = (Dll_SetValue)qLib.resolve("Dll_SetValue");
            if(nullptr == pDll_SetValue2)
                return -2;
    
            pDll_GetValue2 = (Dll_GetValue)qLib.resolve("Dll_GetValue");
            if(nullptr == pDll_GetValue2)
                return -3;
        }
    
        qDebug() << "pDll_SetValue1: " << &pDll_SetValue1;
        qDebug() << "pDll_SetValue2: " << &pDll_SetValue2;
        qDebug() << "pDll_GetValue1: " << &pDll_GetValue1;
        qDebug() << "pDll_GetValue2: " << &pDll_GetValue2;
    
        pDll_SetValue1(234);
        qDebug() << "pDll_SetValue1(234), pDll_GetValue2=" << pDll_GetValue2() << endl;
    
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        loadDll_SameDllTwice();
    
        loadDll_DiffDllOnce();
    
        return a.exec();
    }

    ===========loadDll_SameDllTwice=========
    pDll_SetValue1:  0x60fe14
    pDll_SetValue2:  0x60fe1c
    pDll_GetValue1:  0x60fe18
    pDll_GetValue2:  0x60fe20
    pDll_SetValue1(123), pDll_GetValue2= 123

    ===========loadDll_DiffDllOnce=========
    pDll_SetValue1:  0x60fe14
    pDll_SetValue2:  0x60fe1c
    pDll_GetValue1:  0x60fe18
    pDll_GetValue2:  0x60fe20
    pDll_SetValue1(234), pDll_GetValue2= 0

    展开全文
  • Inject_dylib(indy)允许您加载动态库并在另一个进程中调用函数。 Indy当前支持目标为32位和64位x86进程,可与沙箱互操作,并且已在OS X 10.10上进行了测试。 # include " indy.h " // In your injector process: ...
  • 用MemoryMoudle的类,演示内存加载dll。测试用的dll是我自己写的,里面只有一个函数add,功能是求两数之和。演示程序里button1加载动态库,button2是求1+2的和。非常简单
  • 进程引用的动态链接中的全局变量问题(2012-04-10 23:38:01)标签:多动态杂谈多进程引用的动态链接中的全局变量问题现有liba.so中定义一个全局变量char buf;libb.so 中的函数print会将buf进行输出。进程A和进程...

    多进程引用的动态链接库中的全局变量问题

    (2012-04-10 23:38:01)

    标签:

    动态

    杂谈

    多进程引用的动态链接库中的全局变量问题现有liba.so中定义一个全局变量char buf;

    libb.so 中的函数print会将buf进行输出。

    进程A和进程B使用-lb进行编译链接,并在进程A和B中分别对buf进行初始化,如strcpy(buf,

    "A"); strcpy(buf,

    "B");

    进程A和进程B在初始化后分别通过dlopen的方式加载liba.so并调用其中的print函数。

    输出结果是A中输出A,B中输出B(当然A在初始化buf后sleep一段时间再调用print函数的,而B初始化后直接调用print,这样保证如果只有一份buf则两者输出结果肯定是后初始化的那个值)。

    这是否能确定不同进程加载的动态链接库中的全局变量分别有一份拷贝,即使共享库在内存中只有一份,但是全局变量还是会有多份的,共享库共享的只是代码部分?

    对这种应用方式不太确定。不知是否是这样,测试程序看来是没问题。

    参考地址:

    http://www.linux

    分享:

    a4c26d1e5885305701be709a3d33442f.png喜欢

    0

    a4c26d1e5885305701be709a3d33442f.png赠金笔

    加载中,请稍候......

    评论加载中,请稍候...

    发评论

    登录名: 密码: 找回密码 注册记住登录状态

    昵   称:

    评论并转载此博文

    a4c26d1e5885305701be709a3d33442f.png

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    展开全文
  • 个进程间共享动态链接的原理

    千次阅读 2020-09-19 20:26:27
    操作系统将公用的动态库加载到物理内存中,假设A,B两个进程都需要用到这些dll, 则只需将dll在物理内存中的地址 与 进程A B的虚拟地址空间做一个映射连接。 《Operation system concepts, 7th edition》中的解释...
  • 如何构建可以加载动态库的主机可执行文件。 如何构建带有故意漏洞的动态库。 如何使用dlsym()系列函数在主机运行加载和使用此类库。 这是需要在支持附加库的运行加载的通用语言运行中完成的事情。 在这种...
  • 程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 环境变量LIBRARY_PATH可以指定编译搜索动态库的路径; 环境变量LD_LIBRARY_PATH可以指定程序...
  • 前提:存在一个动态库libvlan.so,存在一个应用console。 做法:在console中调用libvlan.so中的两APIs,分别是设置和获取动态库一个全局变量的值。 结果:在console中的操作没有问题,设置和获取都正常;但在...
  • 那A程序已经运行了,并加载了libc.so到内存,那么此时启动B程序,还需要加载动态库libc.so嘛?还是说B程序直接调用A程序已经加载了libc.so呢? https://blog.csdn.net/YEYUANGEN/article/details/37657937...
  • Linux动态库加载研究

    2022-02-26 22:15:41
    在分析Linux动态库加载过程之前,首先介绍Linux系统中的可执行与可链接格式(Executable and Linkable Format,ELF),该文件格式是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,...
  • 纸上得来终觉浅,这句话一点不假,动态库的知识在看《程序员的自我修养》这本书已经了解了。但是到实际项目遇到问题 却没往这方面去考虑。浪费了半天时间。 问题是这样的:我有模块编译成一so库供其他程序使用...
  • C/C++动态库加载

    千次阅读 2019-07-11 15:44:37
    C/C++动态库加载动态库动态库加载方式链接加载动态加载dlopendlsymdlclosedlerrorextern 'C'参考end 动态库 动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多程序同时使用...
  • 动态链接被多个进程访问

    千次阅读 2018-09-30 23:49:19
    1. 内存页面:系统管理内存的单位。X86系统的内存页面大小都是4KB. 2. 动态链接被多个进程访问 更多内容请看C/C++动态链接(DLL)详解 来源:孙鑫_VC++_学习笔记 ...
  • linux 系统在程序中使用dlopen、dlsym、dlclose、dlerror 显式的加载动态库,需要设置链接选项-ldl 加载动态链接库,首先为共享库分配物理内存,然后在进程对应的页表项中建立虚拟页和物理页面之间的映射。 你可以...
  • 今天项目需要进行同一个dll的多线程同时操作。 解决办法 :通过动态加载的办法 将dll复制重命名 即 线程A-----复制test.dll并重命名为test_A.dll--动态加载test_A.dll 线程B-----复制test.dll并重命名为test_B...
  • http://hi.baidu.com/hust_chen/blog/item/54a8c516231d0c0ec93d6d3e.htmllinux下动态链接加载及解析过程(ZZ)2008-12-18 15:19表面上看,动态链接(dll)的加载及解析是一个十分繁复的过程,其中牵涉到的数据...
  • * 动态库在开发仅是把dll中的函数名和参数放到应用程序中,应用程序运行根据函数名和参数调用dll中的函数来运行,这样操作系统中的应用程序可以同时使用同一个dll。可以有效地节省硬盘空间...
  • 1、loadlibray显式加载时 2、调用了动态链接中函数、定义了类型
  • 、静态库 与汇编生成的目标文件一起链接为可执行文件。一个静态库可以简单看成是组目标文件(.o/.obj...二、动态库 在程序编译并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用...
  • 加载 libnattive.so 动态库、 二、 libnattive.so 动态库启动、 三、 pthread_create 线程开发、 四、 线程执行函数、
  • 程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 优先级(1:最高) 路径 1 编译指定链接的动态库的路径 2 环境变量LD_LIBRARY_PATH所指定的...
  • Linux下不能加载动态库问题 当出现下边异常情况 ./test: error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory 原因: 系统并无此文件 操作系统的中LD_...
  • C/C++:多进程使用dlopen、dlsym、dlclose装载动态库
  • 启动优化之动态库延迟加载

    千次阅读 2018-09-26 19:12:08
     程序启动过程中加载过多动态库会导致启动变慢,尤其是刚开机启动程序,加载过多...静态加载可以使用动态库中的导出函数和导出类,但是静态加载是程序启动时加载动态库,会占用启动时间。动态加载用LoadLibrary函...
  • DLL动态库多次加载问题

    千次阅读 2019-09-29 22:54:05
    原因涉及DLL加载和运行机制,主要有两点:1)DLL动态链接无法独立运行,必须由一个应用程序进程加载到进程空间后才能使用。加载DLL的进程称为宿主进程。被加载的DLL属于宿主进程,不属于宿主进程内某个线程。2)...
  • 功能:显示加在动态库 参数: filename -> 给路径按照路径加载,给文件名就根据LD_LIBRARY_PATH环境变量去查找 flag -> 加载标志 RTLD_LAZY:延迟加载,什么时候真正使用的时候才加载 RTLD_NOW:立即加载 返回值...
  • 根据这想法,查看了一下python的动态加载模块的方法,感觉这想法还是比较靠谱,应该可以实现,所以动手写了小测试验证了把。(这里说明一下,只是验证性的,生产环境要使用的话,还是有不少问题需要考虑的。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,097
精华内容 54,038
热门标签
关键字:

不同进程加载同一个动态库时