对于多线程应用程序中的显示任务,原子锁或互斥锁是必须的吗
Are atomics or mutex locks a must for display tasks in multi threading applications?
我使用的是C++11和内置的线程类std::thread
。使用std::atomic
或std::mutex
可以很容易地同步数据,但我想知道它是否真的有必要用于"非敏感"任务,同时维护一个无错误的应用程序。假设有一个类像
class FPS
{
private:
int rate;
public:
void change(const int i)
{rate = i;}
int read(void)
{return rate;}
};
存储相机的帧速率。在应用程序中,有一个用于数据采集(帧抓取等)的线程读取帧速率,还有另一个线程处理显示帧速率的GUI。在这种情况下,显示是"非关键的",这意味着在某些情况下,允许显示滞后于实际速率。当然,我可以简单地使用原子来确保它的安全,但我仍然想知道,假设应用程序运行在多核CPU上,这是否真的是保证程序无缺陷性能的必要条件。
C++线程模型在代码运行时所做的部分是非常宽松的。您对C++的特定实现可能不会像C++允许的那样疯狂。
依赖它的问题是,如果没有记录和理解它,编译器的下一个迭代版本可能会做出不同的假设,符合C++,并破坏代码。
例如,如果您通过未同步的int
进行通信,编译器可能会注意到无法在此线程中修改数据。如果能够证明这一点,则可以将int
存储在本地寄存器中,并且忽略来自另一个线程的对int
的任何更新。
更重要的是,一段代码可以从寄存器中读取,另一段可以从内存中读取,并且可以有不同的值。更重要的是,对代码中变量的一次读取可能会变成两次读取,而这两次读取可能不一致:我们深陷于未定义行为的领域。
所以,不,一般来说这是不安全的。即使你的测试没有检测到任何问题,没有出现在测试中的线程问题也是非常常见的:测试几乎永远不足以证明你的线程代码是安全的。
它在您的特定编译器、编译器版本和编译器标志上可能是安全的。
http://en.cppreference.com/w/cpp/atomic/memory_order介绍了如何在不完全atomics
的情况下完成。请注意,并不是所有的CPU都会以不同的方式对待这些情况,但有一些体系结构可以区分所有这些情况。我发现所有的内存顺序规则都有点令人困惑,因为我不习惯在它们都存在的系统上工作,但如果你真的需要性能,你可以考虑它
根据我对"性能备忘单"的阅读,原子操作目前是昂贵的,但不是非常昂贵(比如说,比指针指向不在缓存中的内存地址更便宜)。
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 我想通过带有C++和Python的插件创建一个可扩展的应用程序
- 从运行服务的应用程序代码中提取窗口句柄
- 我的应用程序无法在安卓上使用OpenSSL进行链接
- 如何将独立的 c 应用程序组合到 c++ 应用程序中?
- 像 CPP 中的控制台一样的应用程序
- 我的 c++ 应用程序中的运行时间从 0 增加到 60 太快了(例如一毫秒或一微秒)
- 如何编译使用从不同编译器编译的库的应用程序?
- 设置我的应用程序 API 感知并防止系统使其模糊和错误定位
- 为什么Qt Creator的应用程序输出不能从spdlog记录器打印
- 在发布模式下启动使用库的静态链接编译的应用程序时出错
- 是否可以将不同的编译器嵌入到我的应用程序中?
- C++ 无法链接最基本的应用程序
- 在没有Xcode的macOS中开发具有依赖关系的应用程序
- 一个32位版本的应用程序,建立在CentOS 6 x64上,当在较新的Linux上启动时,在"dl_itera
- 我应该使用什么信号来终止/终止Windows上的应用程序
- 使用 pipe() 和 fdopen() 将数据从 Python 脚本传递到 Windows 中的C++应用程序
- eglSwapBuffers上的应用程序崩溃
- 即使在我为我的应用程序授予管理员后也无法从 Windows 系统复制目录
- 在静态库中声明函数,在使用该相同库的应用程序中定义它