我正在使用C++11和内置的线程类std::thread。使用std::atomic或std::mutex可以方便地同步数据,但我想知道,在维护一个没有bug的应用程序的同时,是否真的需要对“非敏感”任务进行同步。比方说有一门课
class FPS
{
private:
int rate;
public:
void change(const int i)
{rate = i;}
int read(void)
{return rate;}
};存储摄像机的帧速率。在应用程序中,有一个线程用于数据采集(帧捕获等)。它读取帧速率,还有另一个线程处理显示帧速率的GUI。在这种情况下,显示是“非关键的”,这意味着在某些情况下允许显示滞后于实际速率。当然,我可以简单地使用一个原子来保证它的安全,但我仍然在想,如果这个应用程序运行在一个多核CPU上,那么它实际上是否必须保证程序的无错误性能。
发布于 2015-04-09 14:46:44
C++线程模型对于代码在运行时所做的操作来说是非常宽松的。您对C++的特定实现可能不会像C++允许的那样疯狂。
依赖它的问题是,如果没有文档化和理解,编译器的下一个迭代版本可能会做出不同的假设,符合C++,并破坏代码。
例如,如果您通过不同步的int进行通信,编译器可能会注意到无法在此线程中修改数据。如果可以证明这一点,则可以将该int存储在本地寄存器中,并忽略来自另一个线程的对int的任何更新。
更重要的是,一段代码可以从寄存器中读取,另一段代码可以从内存中读取,并且您可以具有不同的值。更重要的是,对代码中的变量的读取可以转换为两次读取,而两次读取可能不一致:我们处于未定义行为的深度。
所以不,一般情况下这不安全。即使您的测试没有检测到任何问题,在您的测试中没有出现的线程问题也是非常常见的:测试几乎永远不足以证明您的线程代码是安全的。
在特定的编译器和编译器版本以及编译器标志上,它可能是安全的。
order介绍了如何比完整的atomics做更少的工作。请注意,并不是所有的CPU都会以不同的方式对待这些情况,但是有一些体系结构可以区分所有这些情况。我觉得所有的内存顺序规则都有点令人费解,因为我不习惯在所有这些规则都存在的系统上工作,但是如果您真的需要性能,可以考虑它。
从我读到的“性能备忘单”来看,原子操作目前是很昂贵的,但并不是非常昂贵(例如,比在缓存中引用一个指向内存地址的指针便宜)。
https://stackoverflow.com/questions/29541298
复制相似问题