有没有一种更简单的方法来实例化静态库
Is there a simpler way of instancing a static library?
我有一个静态C库,我需要它来运行多线程(线程之间没有交互,我只需要同时使用多个线程来更快地完成任务)。此外,我还将c库封装到一个c++cli库中,然后由c#main应用程序使用。
由于静态库不能很好地响应通过它运行的多个线程(这超出了我的控制范围,我没有它的依赖项的来源),我已经多次复制(略有变化)整个过程,并在c++cli库(及其副本)和c应用程序之间放置另一个包装器,该应用程序将副本模拟为对象的多达8个实例。它很有效,但对库的功能进行任何更改都相当粗糙和繁琐。
有人知道有什么更简单的方法可以达到同样的效果吗?我的最佳猜测是,一些静态内存是在同一库中工作的多个线程之间发生冲突的地方,有没有办法强制所有静态变量都是线程特定的?(无法在其中添加declspec线程)。
由于您通过C++/CLI层从C#使用C库,因此您的链接关系听起来像这样:
(C#应用程序)--动态-->(C++/CLI DLL)--静态-->(C库)
背景:
因为你说你没有办法修改或以其他方式修复你的C库,所以如果不以某种方式在内存中复制C库,你真的没有办法解决线程安全问题,这将有效地复制全局数据,而全局数据肯定会导致线程冲突。
无论你怎么看,通过DLL复制(你目前的方法)解决这个问题的唯一方法都需要你提前知道你需要多少个复制,而这些DLL中的每一个都需要稍微不同的导出符号名称(例如,每个DLL都需要一个不同的类或名称空间名称作为你的C++/CLI托管对象类)。正如你所说,这确实很粗糙(我将补充一点,很难管理,也不可能扩大规模)。
解决方案:
我认为你更好更干净的选择是通过EXE复制。为此,您将在C++/CLI DLL前面插入一个新的EXE,并通过您选择的IPC机制(C#中的IPC机制-使用和最佳实践)动态链接到它。让我们将此EXE称为您的服务EXE。如果为主C#应用程序中的每个线程实例化一个服务EXE,那么每个服务EXE都将加载其自己的C++/CLI DLL副本,从而加载其自己版本的C库。这意味着每个线程都通过服务EXE对C库的副本进行操作。
以下是您的链接关系:
(C# application)--IPC-->(C# service EXE)--dynamic-->(C++/CLI DLL)--static-->(C library)
在物理文件方面,它看起来是这样的:
MainApp.exe--IPC-->ServiceApp.exe--dynamic-->CppCliWrapper.dll
要优化此解决方案,您应该尽量避免创建/删除繁重的线程,因为这涉及到创建/删除服务EXE。例如,您可以在启动时预先分配X个线程,并在整个应用程序生命周期中使用这些线程。您还可以考虑对操作进行批处理,以优化IPC开销。所有这些都取决于您的应用程序的需求和细节。
更进一步地说,如果您选择通过TCP/IP工作的IPC机制,您可能会在机器之间扩展此解决方案。然后,您可以将操作分散到任意数量的机器上。这就是许多公司将DLL转变为水平可扩展服务的方式。这并不像听起来那么容易,但食物是为了以防万一你需要扩大规模。
问题似乎是库不是可重入的。如果您可以访问库的源代码,那么最好搜索所有全局变量,并使它们成为线程本地变量。这可以在C++11上使用thread_local
关键字来完成,如果使用gcc/g++进行编译,则可以使用__thread
关键字来完成。
这样可以确保在每个线程上使用每个全局变量的不同副本。
- 使用动态实例化的对象填充矢量的快速方法
- 检查类是否在方法中实例化
- 从 c++ 中的实例化进程获取输出的可靠方法是什么?
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 实例化对象并调用方法,使用单行语法在 C# 或 C++ 中返回值?
- 当c++实例化方法?
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C++ 实例化新对象时不接受继承方法默认参数值
- 实例化新类时未调用的方法
- 找不到使用 bitset 实例化模板函数的有效方法
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 有没有一种优雅的方法可以从 std::vector 实例化 boost::array
- 使用类方法而不实例化
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- C++17 单独的显式方法模板实例化声明和定义
- 如何实例化多个 set 对象来测试 Set 类的各种构造函数和方法
- 模板类方法的部分专用化或实例化
- 使用自动>decltype方法显式实例化函数
- 隐式模板方法实例化
- 用虚方法实例化类,但不进行堆分配