我需要以循环方式使用的线程安全的缓冲对象池。我通常只在其中放置一个互斥锁以使增量和模线程安全,但是可以使用std::atomic编写它吗?这是一个示例界面。如果使事情变得容易,缓冲区的总数可以是2的幂。在该类之外永远不会访问下一个缓冲区索引。
class Buffer;
class BufferManager
{
public:
BufferManager( size_t totalBuffers = 8 ) : mNextBufferIndex( 0 ), mTotalBuffers( totalBuffers )
{
mBuffers = new Buffer*[mTotalBuffers];
}
Buffer* GetNextBuffer()
{
// How to make this operation atomic?
size_t index = mNextBufferIndex;
mNextBufferIndex = ( mNextBufferIndex + 1 ) % mTotalBuffers;
return mBuffers[index];
}
private:
Buffer** mBuffers;
size_t mNextBufferIndex;
size_t mTotalBuffers;
};
最佳答案
选择后可以安全使用Modulo
std::atomic<size_t> mNextBufferIndex;
Buffer* GetNextBuffer()
{
// How to make this operation atomic?
size_t index = mNextBufferIndex ++;
size_t id = index % mTotalBuffers;
// If size could wrap, then re-write the modulo value.
// oldValue keeps getting re-read.
// modulo occurs when nothing else updates it.
size_t oldValue =mNextBufferIndex;
size_t newValue = oldValue % mTotalBuffers;
while (!m_mNextBufferIndex.compare_exchange_weak( oldValue, newValue, std::memory_order_relaxed ) )
newValue = oldValue % mTotalBuffers;
return mBuffers[id ];
}