gpt4 book ai didi

boost - 为什么 boost::lockfree::spsc_queue 没有位置?

转载 作者:行者123 更新时间:2023-12-05 02:21:57 28 4
gpt4 key购买 nike

常规 std::vectoremplace_back 避免不必要的复制。 spsc_queue 不支持这个有什么原因吗?是否由于某种原因无法使用无锁队列emplace

最佳答案

我既不是 boost 库的实现者也不是维护者,所以为什么不包含 emplace 背后的基本原理成员函数超出了我的知识范围,但如果您确实需要它,自己实现它并不太难。

spsc_queue有一个基类 compile_time_sized_ringbufferruntime_sized_ringbuffer取决于队列的大小在编译时是否已知。这两个类维护实际使用的缓冲区,动态缓冲区和编译时缓冲区之间存在明显差异,但在本例中委托(delegate)了它们的 push。公共(public)基类的成员函数 - ringbuffer_base .

ringbuffer_base::push函数相对容易理解:

bool push(T const & t, T * buffer, size_t max_size)
{
const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread
const size_t next = next_index(write_index, max_size);

if (next == read_index_.load(memory_order_acquire))
return false; /* ringbuffer is full */

new (buffer + write_index) T(t); // copy-construct

write_index_.store(next, memory_order_release);

return true;
}

下一个项目应该存储的位置的索引是用 relaxed 完成的。加载(这是安全的,因为此类的预期用途是 push 调用的单一生产者)并获取适当的下一个索引,检查以确保一切都在边界内(使用加载获取以与线程适当同步调用 pop ) ,但我们感兴趣的主要语句是:

new (buffer + write_index) T(t); // copy-construct

在缓冲区中执行放置新副本构造。传递一些用于构造 T 的参数本身并没有什么线程不安全的。直接来自可行的构造函数参数。我编写了以下代码片段并在整个派生类中进行了必要的更改,以适本地将工作委托(delegate)给基类:

template<typename ... Args>
std::enable_if_t<std::is_constructible<T,Args...>::value,bool>
emplace( T * buffer, size_t max_size,Args&&... args)
{
const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread
const size_t next = next_index(write_index, max_size);

if (next == read_index_.load(memory_order_acquire))
return false; /* ringbuffer is full */

new (buffer + write_index) T(std::forward<Args>(args)...); // emplace

write_index_.store(next, memory_order_release);

return true;
}

也许唯一的区别是确保在 Args... 中传递的参数实际上可以用来构造一个 T ,当然还有通过 std::forward 进行安置而不是复制构造。

关于boost - 为什么 boost::lockfree::spsc_queue 没有位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31418490/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com