假设我们有一个遗留的C文件,其中包含一些函数来解决线性方程和几个相应的全局变量。
lineq.c:
/* macro definitions */
...
/* global vars */
...
/* some functions that make use of above variables */
void solveLinEq(...);
现在我们想在现代多线程C ++应用程序中使用这个遗留库。因此,我们想要编写一种包装类LinEqSolver
,它提供了一个OO接口来解决线性方程,并在内部调用我们的遗留C库的函数。
但是,应该可能有不同线程使用的LinEqSolver
个多个实例。这要求每个实例/每个线程在lineq.c
中都有自己的全局变量副本。如果我们不想修改lineq.c
?
我能想象的一个可能的解决方案是将全局变量和C文件中的函数复制到类LinEqSolver
中,使它们成为数据和函数成员。然后,LinEqSolver
的每个实例都将对其前全局变量的私有副本进行操作。但是,这种复制粘贴编程风格相当糟糕,尤其是当lineq.c
更新时,我们需要将更改复制粘贴到我们的代码中。
在解决线性方程的实际代码保留在lineq.c
并且只是从LinEqSolver
调用时,我还有哪些其他的可能性?
答案 0 :(得分:1)
您可以将lineq.c
放入共享对象并使用dlopen
和RTLD_PRIVATE
多次加载,并为每个线程使用dlsym
,因此全局变量是独立的每个线程。不幸的是,glibc不支持RTLD_PRIVATE
。解决方法是为每个具有不同名称的线程复制共享对象,并使用dlopen
将RTLD_LOCAL
复制到共享对象的副本lineq.c
。 getElementsByClassName
仍未受到影响。
答案 1 :(得分:1)
您可以使用C ++ 11中的thread_local
关键字。如果您的函数始终在开头初始化所有需要的静态变量,这将很有效。
如果你有更复杂的画面 - 将需要更多的工作。例如:
int myVar1, myVar2;
void InitStaticVars()
{
....
}
void solveLinEq(...);
如果您只是将thread_local
说明符添加到上面的变量并在程序开头调用初始化函数,它将仅为调用线程初始化这些变量。在所有其他线程上,它们的初始值将为零。
答案 2 :(得分:0)
我只想咬紧牙关并修改它以将全局变量添加到一个结构中,该结构应作为指向lineq.c中所有调用的指针传递。
然后很容易用c ++类包装它,每个线程都有一个实例等。
另一种替代方法是修改c文件以使用__declspec(线程)或类似文件。但是,如果您计划将此代码放入dll中,那么您可能会遇到难以解决的问题(至少在Windows上)。