c++ - 条件语句与 std::atomic<T> 的基本用法

标签 c++ c++11 atomic

所以我开始熟悉 C++11 <atomic>类型。过去,当我有一个原子标志时,我通常会在访问它之前简单地锁定一个互斥体。一个常见的需求是检查标志是否为 false ,如果是,则自动将其设置为 true然后做点什么。所以基本上这会像这样完成,其中 flag是一个简单的bool :

{
    std::lock_guard<std::mutex> lock(my_mutex);
    if (!flag) 
    {
        flag = true;
        // do something;
    }
}

所以,现在我正试图弄清楚如何使用 <atomic> 完成同样的事情。 . docs假设赋值运算符和 operator T原子类型的是原子操作。但是,如果我更改 flagstd::atomic<bool> ,我想我不能简单地说:

if (!flag)
{
  flag = true;
  // do something
}

... 因为即使表达式 (!flag)是原子的,赋值 flag = true是原子的,没有什么可以阻止另一个线程修改这两个语句之间的标志。

因此,如果我在这里理解正确,唯一正确的用法 - 完全 - 具有原子类型的条件,其中条件的结果可以修改原子变量,是使用Compare and Swap操作?我说得对吗?

所以,我不得不说:

bool expected = false;
if (flag.compare_exchange_weak(expected, true))
{
   // do something
}

我的理解正确吗?

最佳答案

如果您有多个线程运行相同的代码需要进行翻转,是的 - 您将需要使用 compare_exchange_weak()compare_exchange_strong()正是您建议的原因(可能更喜欢强)。

但是,不能说这是唯一条件与原子的正确用法。比方说,如果我有一个只读取原子的线程和一个写入原子的线程,那么以简单的方式使用它们是完全合理的……例如:

std::atomic<bool> done{false};

// thread 1
while (!done) {
    ....
}

// thread 2
stop() { done = true; }

我没有理由在那里做一个done.compare_exchange_strong(expected, true)。那太过分了。这实际上是根据具体情况而定。

关于c++ - 条件语句与 std::atomic<T> 的基本用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26656823/

相关文章:

c - OpenCL - 双重原子操作 - 工作到极限

multithreading - 您是否期望 future 的 CPU 代不会缓存一致?

c++ - 在 MSMQ 消息中发送具有 BSTR 值类型的 COM 对象

c++ - 如何配置CRC表的计算

c++ - <Winsock.h> 中是否有等效的 MSG_MORE?

c - 具有正确文件长度和缓冲区分配的 fread 段错误

c++ - 如何移动一个 const 返回的对象?

python - 在 Visual Studio 2017 中使用 Pybind11 for Python 构建 CPP 时出现编译错误

c++ - `class template Example<int>;` 语句对 C++11 意味着什么?

c++ - 在C++ 11中是否有任何等于asm (“”::: “memory”)的编译器障碍?