原子增加和比较是线程安全的吗

Posted

技术标签:

【中文标题】原子增加和比较是线程安全的吗【英文标题】:Is atomic increase and comparsion thread-safe 【发布时间】:2017-01-30 08:09:49 【问题描述】:

我正在编写多线程套接字类。可以同时从多个线程调用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;

【问题讨论】:

与您的问题无关,但如果您的三元表达式导致truefalse,则根本不需要三元表达式。在你的最后一个例子中,你也可以写return !x || ( y + 1 &lt;= x); 【参考方案1】:

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

您可以将检查包装在互斥体中,或者想出一种使用单个原子的方法。

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

operator= 以原子方式存储新值

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

operator++ 以原子方式递增一个值

compare_exchange_weak/strong自动检查并设置值

more details

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

【讨论】:

以上是关于原子增加和比较是线程安全的吗的主要内容,如果未能解决你的问题,请参考以下文章

Redis 是并发安全的吗?你确定?

java是线程安全的吗

lua引擎本身是线程安全的吗

Flask-SocketIO 的发射函数线程安全吗?

列表是线程安全的吗?

HashMap是线程安全的吗?如何实现线程安全?