gpt4 book ai didi

c++ - 多线程应用程序中的显示任务必须使用原子锁或互斥锁吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:22:55 33 4
gpt4 key购买 nike

我正在使用 C++11 和内置线程类 std::thread。使用 std::atomicstd::mutex 可以轻松同步数据,但我想知道“非敏感”任务是否真的有必要 - 同时保持一个没有错误的应用程序。假设有一个类

class FPS
{
private:
int rate;
public:
void change(const int i)
{rate = i;}
int read(void)
{return rate;}
};

存储相机的帧率。在应用程序中,有一个线程用于读取帧速率的数据采集(帧抓取等),还有另一个线程处理显示帧速率的 GUI。在这种情况下,显示是“非关键”的,这意味着在某些情况下允许显示滞后于实际速率。我当然可以简单地使用 atomic 来确保它的安全,但我仍然想知道它是否真的必须保证程序的无错误性能,假设应用程序在多核 CPU 上运行。

最佳答案

C++ 线程模型对代码在运行时执行的操作非常宽松。您的特定 C++ 实现可能不像 C++ 允许的那样疯狂。

依赖它的问题是,如果它没有被记录和理解,你的编译器的下一个迭代版本可能会做出不同的假设,与 C++ 兼容,并破坏你的代码。

例如,如果您通过非同步的 int 进行通信,编译器可能会注意到无法在此线程内修改数据。如果它能证明这一点,就可以自由地将 int 存储在本地寄存器中,并忽略任何来自另一个线程的 int 的更新

此外,一段代码可以从寄存器中读取它,另一段代码可以从内存中读取,并且您可以拥有不同的值。更重要的是,对代码中变量的一次读取可能会变成两次读取,并且这两次读取可能不一致:我们深陷未定义行为的领域。

所以不,这通常不安全。即使您的测试未检测到任何问题,未在测试中显示的线程问题也极为常见:测试几乎永远不足以证明您的线程代码是安全的。

它在您的特定编译器和编译器版本以及编译器标志上可能是安全的。

http://en.cppreference.com/w/cpp/atomic/memory_order介绍了如何完成不完整的 atomics。请注意,并非所有 CPU 都会以不同方式处理这些情况,但存在区分所有这些情况的体系结构。我发现所有的内存顺序规则有点莫名其妙,因为我不习惯在它们都存在的系统上工作,但如果你真的需要性能,你可以考虑它。

根据我对“性能备忘单”的阅读,原子操作目前是昂贵的,但不是非常昂贵(比说,遵循指向不在缓存中的内存地址的指针更便宜)。

关于c++ - 多线程应用程序中的显示任务必须使用原子锁或互斥锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541298/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com