简体   繁体   中英

Is atomic increase and comparsion thread-safe

I'm writing multithreaded socket class. BelowBounds() function can be invoked from multiple threads simultaneously, i need to prevent using mutexes. Does this code is thread-safe ?

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;
    }
}

Or i must write in this way?

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

Both of your alternatives are unsafe. Each atomic variable by itself is atomic, but using two of them in a single statement is not.

You can wrap your check in a mutex or come up with a way to use a single atomic.

What operations on std::atomic are atomic?

  • operator= stores a new value atomically

  • load() or operator T (using in an expression) reads the value atomically

  • operator++ increments a value atomically

  • compare_exchange_weak/strong check and set the value atomically

  • more details

Using two atomics in an expression is not atomic: a + b will read a atomically, then read b atomically, but anything can happen in between reading a and b ; by the time you read b , a can already have another value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM