【问题标题】:C++ atomic CAS(compare-and-swap) operation does not change valueC++ 原子 CAS(比较和交换)操作不会改变值
【发布时间】:2020-07-12 15:38:59
【问题描述】:

在以下示例中,实际发生了什么?为什么兑换成功后价值没有变化?

直播:https://wandbox.org/permlink/f5VYSKfQ9UJqa8FQ

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

int main()
{
    std::thread thread([](){
        while(true){        
            // wait until flag not becomes true
            {
              bool expect = true;
              while(!flag.compare_exchange_strong(expect, false, std::memory_order_acq_rel)){
                  std::cout << "wait" << std::endl;
              }
            }
            
            std::cout << "work" << std::endl;
        }
    });
    flag.store(true, std::memory_order_release);
    thread.join();
}

输出:

work
wait
work
wait
...

【问题讨论】:

  • 我不明白你的问题。您希望看到什么输出?
  • 我认为你不明白 compare_exchange_strong 做了什么。这是一个复杂的操作。阅读有关它的参考资料en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
  • @jtbandes 我希望“等待等待工作等待等待......”

标签: c++ atomic compare-and-swap


【解决方案1】:

考虑会发生什么:

          bool expect = true;
          while(!flag.compare_exchange_strong(expect, false, std::memory_order_acq_rel)){
              std::cout << "wait" << std::endl;
          }

当标志为假时。 while 循环中的测试第一次运行时,expect 将为真,因此与标志不匹配。所以expect更新为false,函数返回false。所以wait 被打印出来并且循环重复。 循环中的第二个测试,expect 现在将是 false,它与 flag 匹配,所以 flag 将被设置为 false(它已经是一个 noop),并且循环将退出。

最终结果是始终将flag 设置为false,如果wait 已经是false,则打印它。因此,您看到的输出。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 2011-10-29
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多