博客
关于我
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/

    你可能感兴趣的文章
    NOI-1.3-11-计算浮点数相除的余数
    查看>>
    noi.ac #36 模拟
    查看>>
    NOI2010 海拔(平面图最大流)
    查看>>
    NOIp2005 过河
    查看>>
    NOIP2011T1 数字反转
    查看>>
    NOIP2014 提高组 Day2——寻找道路
    查看>>
    noip借教室 题解
    查看>>
    NOIP模拟测试19
    查看>>
    NOIp模拟赛二十九
    查看>>
    Vue3+element plus+sortablejs实现table列表拖拽
    查看>>
    Nokia5233手机和我装的几个symbian V5手机软件
    查看>>
    non linear processor
    查看>>
    Non-final field ‘code‘ in enum StateEnum‘
    查看>>
    none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)
    查看>>