gpt4 book ai didi

使用 std::atomic 的 C++ 线程安全增量,带模而不带互斥锁

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:43:44 24 4
gpt4 key购买 nike

我需要一个以循环方式使用的线程安全缓冲区对象池。我通常会在其中放置一个互斥锁以使增量和模线程安全,但是是否可以使用 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;
};

最佳答案

取模后可以放心使用

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

关于使用 std::atomic 的 C++ 线程安全增量,带模而不带互斥锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33554255/

24 4 0