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
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.