如何制作线程本地库实例?
Posted
技术标签:
【中文标题】如何制作线程本地库实例?【英文标题】:How to make thread-local library instance? 【发布时间】:2019-11-07 17:20:58 【问题描述】:我们在工作场所使用旧版库。它包含一些业务逻辑,它的代码在千年变化之前就已经丢失了。代码包含一些硬金融算法,它积极使用全局变量。
我们计划进行一些并行计算,启动新线程。每个线程都将独立于另一个线程,只是一个返回一些数字的黑盒。
核心问题是库不是线程安全的。我们希望以某种方式使每个线程都有自己的共享库中的全局变量、代码等副本。
这可能吗?目前,我们只是修补符号名称并使用前缀进行复制。
library-thread1.so
、library-thread2.so
等
在linux下使用RTLD_DEEPBIND
加载符号。
编辑:用进程替换线程是解决这个问题的最严格的方法,但它会引起对性能的担忧。而且似乎工作量很大,而不仅仅是做肮脏的黑客。
【问题讨论】:
用“进程”代替“线程”当然是可以的。否则它可能是可能的,但看起来很脆弱且容易出错。 在之前的工作中,我们遇到了类似的问题,需要一个进程来加载负责与服务总线进行网络通信的库的不同版本。这对于允许一项服务与运行不兼容版本的有线协议的多条总线进行通信是必要的。我们的解决方案是构建一个 COM 服务并创建进程外实例。您也许可以做同样的事情:创建一个进程外 COM 服务并创建多个实例。当然会有一些 IPC 开销,但这在您的用例中可能并不重要。 全局变量是 process 全局的,因此一个线程不足以隔离它们。在并行化您的工作时,请考虑生成多个单独的进程。 【参考方案1】:核心问题是库不是线程安全的。
使用进程,而不是线程。该库将自动实现多进程安全,无需任何努力或意外共享的风险。
我们希望以某种方式使每个线程都有自己的来自共享库的全局变量、代码等的副本。
具有此属性的线程称为进程。进程——主要是——不共享全局变量的线程(包括文件描述符、std::cout
缓冲区等)。
在 Linux 或 *NIX 上,进程通常不会比线程更昂贵或通信速度更慢。
用进程替换线程是解决这个问题最严格的方法,但它会引起对性能的担忧
这样做,然后衡量性能。如果确实存在问题,您可以在 Linux 上使用共享内存来保持线程的有效零开销通信,同时保持正确的语义。
而且似乎工作量很大,而不仅仅是做肮脏的黑客。
当一切都出错并且你无法弄清楚原因时,更多地担心支持肮脏的黑客需要做多少工作。
【讨论】:
这当然不能回答我的问题。 好吧,您的问题预先假定线程和进程之间以及进程间和线程间通信的性能之间存在严格的区别。这个假设是错误的,所以框架挑战似乎是一个合理的回应。如果您在流程方面遇到了真实而非想象的问题,或者您需要帮助了解如何使用它们,请提出那个问题。 顺便说一句,我完全不知道如何在 Windows 上解决这个问题。无论如何,试图将两种截然不同的流程模型归为一个答案似乎有些过分,但我不知道最好的解决方案可能在两个平台上都是相同的。以上是关于如何制作线程本地库实例?的主要内容,如果未能解决你的问题,请参考以下文章
如何将C / C ++库代码封装为可在具有多个实例的单独线程中运行?