原子增加和比较线程安全

Is atomic increase and comparsion thread-safe

本文关键字:线程 安全 比较 增加      更新时间:2023-10-16

我正在编写多线程套接字类。 BelowBounds() 函数可以同时从多个线程调用,我需要防止使用互斥锁。这段代码是线程安全的吗?

class UDPSocketHT
{
public:
    std::atomic<size_t> m_nSimultaneousRecvCalls;
    std::atomic<size_t> m_nPendingOperations;
    //...
    bool UDPSocketHT::BelowBounds ( )
    {
         return ( !m_nSimultaneousRecvCalls || ( m_nPendingOperations + 1 <= m_nSimultaneousRecvCalls ) ) ? true : false;
    }
}

还是我必须这样写?

bool UDPSocketHT::BelowBounds ( )
{
     size_t x = m_nSimultaneousRecvCalls;
     size_t y = m_nPendingOperations;
     return ( !x || ( y + 1 <= x) ) ? true : false;
}

您的两种选择都是不安全的。每个原子变量本身都是原子变量,但在单个语句中使用其中两个不是原子变量。

您可以将支票包装在互斥锁中,也可以想出一种使用单个原子的方法。

std::atomic上的哪些操作是原子的?

  • operator=以原子方式存储新值

  • load()operator T(在表达式中使用)以原子方式读取值

  • operator++以原子方式递增值

  • compare_exchange_weak/strong检查并以原子方式设置值

  • 更多详情

在表达式中使用两个原子不是原子的:a + b以原子方式读取a然后以原子方式读取b,但是在读取ab之间可能发生任何事情;当你读取b时,a已经可以有另一个值了。