博客
关于我
C/C++:多进程使用dlopen、dlsym、dlclose装载动态库
阅读量:208 次
发布时间:2019-02-28

本文共 2200 字,大约阅读时间需要 7 分钟。

动态库在多进程环境下的行为可能会让人产生一些误解。很多人认为,同一动态库被多个进程打开时,实际上是共享同一个实例。这并不完全正确。实际上,每个进程在装载动态库时,会创建属于自己的独立实例。尽管动态库的代码和符号可能被多个进程共享,但每个进程都有自己独特的全局变量和互斥锁。这种行为会导致多个进程在使用相同动态库时,彼此之间无法直接看到对方的动态库实例。

为了验证这一点,我设计了一个简单的测试案例。以下是测试的详细步骤:

  • 创建头文件(count.h)
  • #ifndef _COUNT_H#define _COUNT_H#include 
    int count;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int get();void inc();#endif
    1. 创建源文件(count.c)
    2. #include "count.h"int get() {    return count;}void inc() {    pthread_mutex_lock(&mutex);    count++;    pthread_mutex_unlock(&mutex);}
      1. 创建主程序(main.c)
      2. #include 
        #include
        #include
        #include
        #include
        #define NUM 1000#define LIBPATH "/home/test1280/libcount.so"void *ThreadRun(void *arg) { void *handler = dlopen(LIBPATH, RTLD_LAZY); if (handler == NULL) { printf("ERROR:%s:dlopen\n", dlerror()); return; } void (*inc)() = (void (*)())dlsym(handler, "inc"); if (inc == NULL) { printf("ERROR:%s:dlsym\n", dlerror()); return; } int (*get)() = (int (*)())dlsym(handler, "get"); if (get == NULL) { printf("ERROR:%s:dlsym\n", dlerror()); return; } int i = 0; for (; i < NUM; i++) { inc(); usleep(1000 * 1000); printf("INFO:PID(%d):%d\n", getpid(), get()); } dlclose(handler);}int main() { pthread_t tid; pthread_create(&tid, NULL, ThreadRun, NULL); printf("create Thread OK!!!\n"); while (1); // 按住控制台,观察输出 return 0;}
        1. 编译和链接
        2. gcc -fPIC -c count.cgcc -shared count.o -o libcount.sogcc -o main main.c -ldl -lpthread
          1. 执行测试
            • 在终端A中运行主程序:
            ./main
            • 在终端B中立即运行主程序:
            ./main

            观察输出结果:

            • 终端A输出:
              create Thread OK!!! INFO:PID(5645):1 INFO:PID(5645):2 INFO:PID(5645):3 ...
            • 终端B输出:
              create Thread OK!!! INFO:PID(5689):1 INFO:PID(5689):2 INFO:PID(5689):3 ...

            从输出结果可以看出,两个进程各自独立地创建了自己的动态库实例,计数器从头开始,互不影响。这说明每个进程在装载动态库时,实际上是创建了独立的实例,包括各自的全局变量和互斥锁。

            通过这些实验,我得出以下结论:

            • 动态库实例是进程私有的:每个进程在装载动态库时,会创建属于自身的独立实例。虽然动态库文件可能被多个进程共享,但每个进程都有自己独特的实例。
            • 全局变量和互斥锁属于特定进程:同一动态库中的全局变量和互斥锁不会在多个进程之间共享。这意味着不同的进程在使用动态库时,无法直接访问对方的进程中的全局变量。
            • 需要谨慎管理共享资源:在多进程环境中使用动态库时,特别是在共享敏感资源时,需要采取措施确保数据的一致性和互斥性。

            这些了解对于开发和优化多线程或多进程程序尤为重要。通过正确管理动态库的装载和使用,可以避免潜在的竞态条件和数据不一致问题。

    转载地址:http://gtgs.baihongyu.com/

    你可能感兴趣的文章
    oracle表访问方式
    查看>>
    Oracle触发器
    查看>>
    Oracle计划将ZGC项目提交给OpenJDK
    查看>>
    oracle账号共享
    查看>>
    Oracle闪回技术(Flashback)
    查看>>
    oracle零碎要点---ip地址问题,服务问题,系统默认密码问题
    查看>>
    oracle零碎要点---oracle em的web访问地址忘了
    查看>>
    Oracle零碎要点---多表联合查询,收集数据库基本资料
    查看>>
    Oracle静默安装
    查看>>
    Oracle面试题:Oracle中truncate和delete的区别
    查看>>
    ThreadLocal线程内部存储类
    查看>>
    thinkphp 常用SQL执行语句总结
    查看>>
    Oracle:ORA-00911: 无效字符
    查看>>
    Text-to-Image with Diffusion models的巅峰之作:深入解读 DALL·E 2
    查看>>
    TCP基本入门-简单认识一下什么是TCP
    查看>>
    tableviewcell 中使用autolayout自适应高度
    查看>>
    Orcale表被锁
    查看>>
    svn访问报错500
    查看>>
    Orderer节点启动报错解决方案:Not bootstrapping because of 3 existing channels
    查看>>
    org.apache.ibatis.exceptions.PersistenceException:
    查看>>