Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
console::MultiLFQueue< T, Alloc, RobinTimes > Class Template Reference

多队列版本的 LFQueue,将数据分布到多个独立的 LFQueue 中以提高并发性能。 More...

#include <queue.h>

Public Member Functions

 MultiLFQueue (size_t num_queues=1)
 构造函数,初始化指定数量的子队列。
template<class... Args>
auto push (Args &&...args) -> decltype(queues_[_index()]->push(std::forward< Args >(args)...))
 将数据推送到队列中。
bool pop (T &output)
 从队列中弹出数据。
std::unique_ptr< T > pop ()
 从队列中弹出数据,并返回一个独占所有权的 std::unique_ptr。
template<class Iterator>
size_t pop (Iterator output, size_t count)
 从队列中弹出大批数据,写入输入迭代器。
template<class Iterator>
size_t pop (Iterator begin, Iterator end)
 从队列中弹出数据大批数据,写入输出迭代器。
std::vector< T > pop (size_t count)
 从队列中弹出数据大批数据,返回包含弹出结果的 vector。

Private Member Functions

size_t _index ()
 获取当前线程的索引,用于推送时的负载均衡。
template<class OtherIterator, class IteratorTag>
void _advance (OtherIterator &it, size_t n, IteratorTag)
 类似标准库的 advance。
template<class RandomAccessIterator>
void _advance (RandomAccessIterator &it, size_t n, std::random_access_iterator_tag)
 类似标准库的 advance。
template<class Iterator>
void _advance (Iterator &it, size_t n)
 类似标准库的 advance。

Private Attributes

std::vector< std::unique_ptr< console::LFQueue< T, Alloc > > > queues_
 子队列集合,每个子队列用于存储不同线程的队列数据。
std::atomic< size_t > round_robin_ {0}
 轮询计数器,用于弹出时的负载均衡。
std::atomic< size_t > nth_ {0}
 序号计数器,用于推送时的线程索引分配。

Detailed Description

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
class console::MultiLFQueue< T, Alloc, RobinTimes >

多队列版本的 LFQueue,将数据分布到多个独立的 LFQueue 中以提高并发性能。

Template Parameters
T队列中元素的类型。
Alloc分配器类型,默认为 std::allocator<T>。
RobinTimespop 轮询次数,默认为 2。
Note
通过多个子队列减少竞争者数量,降低自旋等待的概率。 推送时使用线程本地索引进行负载均衡,弹出时使用轮询策略遍历所有子队列。
Warning
不保证多线程的全局 FIFO 顺序,仅保证每个线程内部的 FIFO 顺序。

Constructor & Destructor Documentation

◆ MultiLFQueue()

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
console::MultiLFQueue< T, Alloc, RobinTimes >::MultiLFQueue ( size_t num_queues = 1)
inline

构造函数,初始化指定数量的子队列。

Parameters
num_queues子队列的数量。

Member Function Documentation

◆ _advance() [1/3]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class Iterator>
void console::MultiLFQueue< T, Alloc, RobinTimes >::_advance ( Iterator & it,
size_t n )
inlineprivate

类似标准库的 advance。

Note
令我深痛恶觉的是,就我机器上的 GCC 实现, std::advance 不支持 OutputIterator,我也不知道为什么。

◆ _advance() [2/3]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class OtherIterator, class IteratorTag>
void console::MultiLFQueue< T, Alloc, RobinTimes >::_advance ( OtherIterator & it,
size_t n,
IteratorTag  )
inlineprivate

类似标准库的 advance。

Note
令我深痛恶觉的是,就我机器上的 GCC 实现, std::advance 不支持 OutputIterator,我也不知道为什么。

◆ _advance() [3/3]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class RandomAccessIterator>
void console::MultiLFQueue< T, Alloc, RobinTimes >::_advance ( RandomAccessIterator & it,
size_t n,
std::random_access_iterator_tag  )
inlineprivate

类似标准库的 advance。

Note
令我深痛恶觉的是,就我机器上的 GCC 实现, std::advance 不支持 OutputIterator,我也不知道为什么。

◆ _index()

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
size_t console::MultiLFQueue< T, Alloc, RobinTimes >::_index ( )
inlineprivate

获取当前线程的索引,用于推送时的负载均衡。

Returns
线程索引。

◆ pop() [1/5]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
std::unique_ptr< T > console::MultiLFQueue< T, Alloc, RobinTimes >::pop ( )
inline

从队列中弹出数据,并返回一个独占所有权的 std::unique_ptr。

Returns
如果成功弹出数据,则返回一个包含数据的 std::unique_ptr;否则返回 nullptr。
Note
将实际工作委托至 pop(T &)。

◆ pop() [2/5]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class Iterator>
size_t console::MultiLFQueue< T, Alloc, RobinTimes >::pop ( Iterator begin,
Iterator end )
inline

从队列中弹出数据大批数据,写入输出迭代器。

Parameters
begin输出迭代器的起始位置,用于写入弹出的数据。
end输出迭代器的结束位置。
Returns
实际弹出的数据数量。
Note
将实际工作委托至 pop(Iterator, size_t)。

◆ pop() [3/5]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class Iterator>
size_t console::MultiLFQueue< T, Alloc, RobinTimes >::pop ( Iterator output,
size_t count )
inline

从队列中弹出大批数据,写入输入迭代器。

Parameters
output输出迭代器,用于存储弹出的数据。
count要弹出的数据数量。
Returns
实际弹出的数据数量。

◆ pop() [4/5]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
std::vector< T > console::MultiLFQueue< T, Alloc, RobinTimes >::pop ( size_t count)
inline

从队列中弹出数据大批数据,返回包含弹出结果的 vector。

Parameters
count要弹出的数据数量。
Returns
实际弹出的数据,通过 .size() 获取数据数量。
Note
将实际工作委托至 pop(Iterator, size_t)。

◆ pop() [5/5]

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
bool console::MultiLFQueue< T, Alloc, RobinTimes >::pop ( T & output)
inline

从队列中弹出数据。

Parameters
output弹出的数据将存储在此处。
Returns
如果成功弹出数据,则返回 true;否则返回 false。
Note
使用轮询计数器 round_robin_ 选择起始子队列,然后依次遍历所有子队列, 直到找到一个非空的子队列并成功弹出数据。如果所有子队列均为空,则返回 false。 可能佯败,如果在询问过一个子队列之后改子队列才被 push,则发生佯败。

◆ push()

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
template<class... Args>
auto console::MultiLFQueue< T, Alloc, RobinTimes >::push ( Args &&... args) -> decltype(queues_[_index()]->push(std::forward< Args >(args)...))
inline

将数据推送到队列中。

Template Parameters
Args参数类型包,支持 const T&、T&& 以及批量迭代器形式。
Parameters
args要推送的数据参数,转发给子队列的 push 方法。
Returns
子队列 push 方法的返回值 (void 或相关类型)。
Note
使用线程本地索引选择子队列进行负载均衡,减少多线程竞争。

Member Data Documentation

◆ nth_

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
std::atomic<size_t> console::MultiLFQueue< T, Alloc, RobinTimes >::nth_ {0}
private

序号计数器,用于推送时的线程索引分配。

◆ queues_

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
std::vector<std::unique_ptr<console::LFQueue<T, Alloc> > > console::MultiLFQueue< T, Alloc, RobinTimes >::queues_
private

子队列集合,每个子队列用于存储不同线程的队列数据。

◆ round_robin_

template<class T, class Alloc = std::allocator<T>, size_t RobinTimes = 2>
std::atomic<size_t> console::MultiLFQueue< T, Alloc, RobinTimes >::round_robin_ {0}
private

轮询计数器,用于弹出时的负载均衡。


The documentation for this class was generated from the following file: