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

    你可能感兴趣的文章
    nginx 后端获取真实ip
    查看>>
    Nginx 学习总结(16)—— 动静分离、压缩、缓存、黑白名单、性能等内容温习
    查看>>
    Nginx 学习总结(17)—— 8 个免费开源 Nginx 管理系统,轻松管理 Nginx 站点配置
    查看>>
    Nginx 常用配置清单
    查看>>
    nginx 常用配置记录
    查看>>
    Nginx 我们必须知道的那些事
    查看>>
    Nginx 的 proxy_pass 使用简介
    查看>>
    Nginx 的配置文件中的 keepalive 介绍
    查看>>
    Nginx 负载均衡与权重配置解析
    查看>>
    Nginx 负载均衡详解
    查看>>
    nginx 配置 单页面应用的解决方案
    查看>>
    nginx 配置https(一)—— 自签名证书
    查看>>
    nginx 配置~~~本身就是一个静态资源的服务器
    查看>>
    Nginx 配置解析:从基础到高级应用指南
    查看>>
    nginx+Tomcat性能监控
    查看>>
    Nginx下配置codeigniter框架方法
    查看>>
    nginx报错:the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:128
    查看>>
    nginx添加模块与https支持
    查看>>
    Nginx用户认证
    查看>>
    Nginx的Rewrite正则表达式,匹配非某单词
    查看>>