在多核环境中进行编码时,需要注意的是什么?
例如,对于单例类,最好创建一个全局对象,然后返回其引用而不是静态对象。
即 而不是
MyClass & GetInstance()
{
static Myclass singleMyclass;
return singleMyclass;
}
最好有
Myclass singleMyclass;
MyClass & GetInstance()
{
return singleMyclass;
}
许多线程可能同时调用GetInstance()。
修改
我的问题是关于c ++的隐藏结构,在多线程程序中使用它们时必须注意这些结构。在上面的例子中,static不是线程安全的,因为编译器为静态对象添加了一些指令,这不是线程安全的。我正在寻找一个应该注意的类似结构。
答案 0 :(得分:3)
你必须小心初始化静力学。初始化的顺序可能会在复杂系统中造成严重破坏,其中静态对象在其构造函数中执行大量操作。
第一种方法更好,因为单身人士是按需创建的,但是你需要一些锁定来使其线程安全。
第二种方法是线程安全的,因为初始化是在创建任何线程之前完成的(假设你的静态对象没有启动线程运行),但是顺序或初始化可能是一个大问题!如果静态对象在实例化singleMyclass之前从其构造函数中调用GetInstance(),该怎么办? (提示:它不漂亮!)
我建议使用第一种方法,但请阅读Double-checked locking,但要小心,因为它doesn't actually work
请务必阅读Dobb博士的文章。
答案 1 :(得分:1)
我的第一个答案解决了你的单例初始化的例子,但正如你在编辑问题中所强调的那样,当我们转向多核和多线程应用程序时,你正处于C ++的更普遍的陷阱之后。当您第一次遇到它时,以下是一个真正的惊喜。虽然不是特定于C ++,但它肯定会影响C ++代码。
乱序执行和内存障碍(或围栏):
一个问题是无序执行。由于现代硬件允许乱序执行优化,线程可能无序地查看在不同核上执行的其他线程的操作。因此,在单核机器上正确运行的多线程编码实际上在多核机器上可能是不正确的。
解决此类问题的一个天真的解决方案是扩大关键部分的范围。另一种方法是使用memory barriers或无锁算法。
答案 2 :(得分:0)
多核并不是那么相关,因为你也可能在unicore系统上获得多个线程。
两个版本的GetInstance()看起来都像在那里工作一样,如果他们做任何非线程安全的事情,那么需要进行正确锁定等的类方法。
答案 3 :(得分:-1)
我基于它的标题渴望这个问题,但现在却完全没有看到它的相关性。
编程多核的问题基本上是,如何构建程序以使这些核获得最大负载;换句话说,如何并行化您的应用程序。
对于拥有C ++项目的人来说,这方面的热门建议是Intel Threading Building Blocks库(和book)。它试图解决问题,将它们隐藏在模板类之后。我认为它做得很好。