我试图更深入地了解在 C++ 11 中编写多线程应用程序时我有多少选项。
简而言之,到目前为止我看到了这 3 个选项:
- 具有显式锁定和释放机制的互斥体,它们通过锁定和释放来保持线程同步,这很昂贵并且不能保证我的代码执行的顺序,但通常这种解决方案在不同的内存模型之间是非常可移植的。
- 原子操作,由于 atomic = 1single operation without a race 并且始终是一致的,sync 是在不加锁和释放的情况下完成的,没有race 就不需要加锁,具有高度优化的原子操作,但是 atomics 仍然不能保证我的代码将执行的顺序。
- 栅栏,它们在我的代码中创建了一个块,编译器无法重新排序任何内容,灵活性较低,并且它们在代码维护方面往往成本高昂,因为我总是必须关注真正正在执行的内容以及按什么顺序,但它们也改进了缓存技术,在这 3 种解决方案中,它们可能是行为最可预测的一种。
这或多或少是我从关于线程和内存模型的第一堂课中学到的核心,我的问题是:
我打算使用无锁数据结构和原子来实现灵活性和良好的性能,这里的问题是,显然 X86 机器执行的内存重新排序与 ARM 机器不同,我希望尽可能地保持我的代码可移植至少在这两个平台上,那么当两个平台不能保证具有相同的重新排序机制时,你可以建议什么样的方法来编写一个可移植的多线程软件?或者原子操作是最好的选择,因为它现在是我错了?
例如,我注意到英特尔 TBB 库(不是 C++11 代码)正在移植到 ARM/Android,并对专用于原子的部分进行了大量修改,所以也许我可以用 C+ 编写可移植的多线程代码+11,使用无锁数据结构,并在稍后将我的库移植到另一个平台时优化有关原子的部分?