加载共享库的多个副本

mos*_*man 12 c c++ linux shared-libraries thread-safety

我正在运行Linux,我希望能够将并行函数调用到共享库(.so)中,遗憾的是它不是线程安全的(我猜它有全局数据结构).

出于性能原因,我不想简单地将函数调用包装在互斥锁中.

我想做的是产生4个线程,并将同一个库的4个副本加载到进程内存中.然后每个线程将函数调用到它自己的库副本中.

不幸的是,dlopen不允许我加载任何库的更多一个实例.

有谁知道任何允许我多次加载库的方法?(除了制作4个.so文件的副本,每个都有不同的名称)

Emp*_*ian 9

可以加载库的多个独立副本,如下所示:

#define _GNU_SOURCE
#include <dlfcn.h>
...
void *handle = dlmopen(LM_ID_NEWLM, "/path/to/library.so", RTLD_NOW);
Run Code Online (Sandbox Code Playgroud)

更多信息在这里.

  • 你可能会错过`dlmopen()`的一个限制是(截至今天),glibc实现每个进程限制为16个命名空间.每次使用`LM_ID_NEWLM`调用`dlmopen()`时,都会使用其中一个命名空间(直到卸载该命名空间中的所有模块). (3认同)

小智 6

您可以使用多个进程,而不是使用线程,每个进程都执行一些工作.这在*nix上很常见,通常更容易编码.

  • @Charles:全部取决于线程/进程之间的共享数据量.使用流程的好处在于它通过良好控制的通信系统实现了良好的程序设计.线程的明显简单性通常是糟糕的设计. (3认同)
  • 我不知道更容易编码.当然,调用`fork()`稍微容易一点就是启动一个线程.但是,如果您需要在进程之间进行通信,或者在进程之间共享数据,那么您将进入IPC(共享内存,管道等)的世界,这可能会使代码更加复杂. (2认同)
  • 对于初学者来说,使用他的非线程安全库更容易.:)我觉得编码更容易,因为它更容易避免死锁和相关问题,但是,是的,他们在IPC中也有自己的版本. (2认同)