如何将C / C ++库代码封装为可在具有多个实例的单独线程中运行?

问题描述 投票:4回答:3

想象一个项目的开发时间超过10年。一些部分在C中,一些在C ++中,所有代码都使用全局函数和全局变量。该架构本身设计为单线程,并以此方式保持增长。但现在我们考虑使用多核架构。

现在要评估的一个想法是将一部分代码重构到库中,以便创建多个实例,这样它们就可以在不同的线程中运行,而不会相互干扰。

此时获得最多牵引力的提议是将所有库文件包装到具有宏定义的命名空间中,例如:

namespace VARIANT {
    // all the code
}

然后在标题或项目级别定义VARIANT。这将使得在不同名称空间内具有不同的上下文成为可能。而卖点是这种方法需要最少的代码更改,并且引入任何回归的风险都很低。

但是,如果在某些时候我们需要使Variant1的行为与Variant2不同,那么事情会变得棘手,因为没有办法将宏定义的值与预处理器宏中的字符串进行比较。

是否有更优雅的方式来实现这一目标?

c++ c macros namespaces
3个回答
4
投票

另一种变体可能是发现所有全局变量并使它们成为thread_local。需要C ++ 11或至少提供相同的编译器扩展(使用较旧的GCC的__thread)。

如果我正确阅读this question,你甚至不需要将你的C文件转换为C ++文件(你的方法需要,因为C不支持命名空间...),但你需要C11。


1
投票

重构旧项目并使其成为多线程并不是那么简单。首先,你有C和C ++代码的混合,你不能盲目地遵循C ++方法。您需要在以下区域中使用以下内容来代替命名空间: -

  1. 找出所有代码块,像listlarge array等需要同步的对象等容器。
  2. 找出线程的相互依赖性以及如何控制它们。例如,一个线程将生成一个报告并插入到表中,第二个线程需要该信息来生成其最终报告,现在您需要在代码库中的线程中找出这种依赖关系并需要找出它们的控制机制。
  3. C ++中的旧式多线程非常棘手,因此您需要将代码迁移到C ++ 11,其中多线程的实现更加容易。
  4. 正如你所说,在你当前的项目中有很多全局变量,你需要正确思考如何在不同的线程之间共享这些变量,以及如何同步这些变量的访问。

这些是一些提示,你需要在开始重构之前提前考虑很多方面,否则你所有的努力都会结束。

祝你的计划好运。


1
投票

只需按步骤进行,每次测试:

1)typedef一个包含所有全局变量的结构。 malloc one,并编辑现有代码以引用它。测试 - 应该与全局变量完全相同。

2)创建一个线程来运行一个代码实例。测试 - 应该与全局变量完全相同。

3)尝试多个线程。

一步一步来...

请尽量不要尝试任何礼物!

© www.soinside.com 2019 - 2024. All rights reserved.