...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::lockfree::spsc_queue
// In header: <boost/lockfree/spsc_queue.hpp> template<typename T, typename A0, typename A1> class spsc_queue { public: // types typedef T value_type; typedef implementation_defined::allocator allocator; typedef implementation_defined::size_type size_type; // member classes/structs/unions template<typename T, typename... Options> struct implementation_defined { // types typedef allocator_arg allocator; typedef std::size_t size_type; }; // construct/copy/destruct spsc_queue(void); template<typename U> explicit spsc_queue(typename allocator::template rebind< U >::other const &); explicit spsc_queue(allocator const &); explicit spsc_queue(size_type); template<typename U> spsc_queue(size_type, typename allocator::template rebind< U >::other const &); spsc_queue(size_type, allocator_arg const &); // public member functions bool push(T const &); bool pop(); template<typename U> boost::enable_if< typename is_convertible< T, U >::type, bool >::type pop(U &); size_type push(T const *, size_type); template<size_type size> size_type push(T const (&)); template<typename ConstIterator> ConstIterator push(ConstIterator, ConstIterator); size_type pop(T *, size_type); template<size_type size> size_type pop(T(&)); template<typename OutputIterator> boost::disable_if< typename is_convertible< T, OutputIterator >::type, size_type >::type pop(OutputIterator); template<typename Functor> bool consume_one(Functor &); template<typename Functor> bool consume_one(Functor const &); template<typename Functor> size_type consume_all(Functor &); template<typename Functor> size_type consume_all(Functor const &); size_type read_available() const; size_type write_available() const; const T & front() const; T & front(); void reset(void); };
The spsc_queue class provides a single-writer/single-reader fifo queue, pushing and popping is wait-free.
Policies:
boost::lockfree::capacity<>
, optional
If this template argument is passed to the options, the size of the ringbuffer is set at compile-time.
boost::lockfree::allocator<>
, defaults to boost::lockfree::allocator<std::allocator<T>>
Specifies the allocator that is used to allocate the ringbuffer. This option is only valid, if the ringbuffer is configured to be sized at run-time
Requirements:
T must have a default constructor
T must be copyable
spsc_queue
public
construct/copy/destructspsc_queue(void);
Constructs a spsc_queue
Requires: |
spsc_queue must be configured to be sized at compile-time |
template<typename U> explicit spsc_queue(typename allocator::template rebind< U >::other const &);
explicit spsc_queue(allocator const &);
explicit spsc_queue(size_type element_count);
Constructs a spsc_queue
for element_count elements
Requires: |
spsc_queue must be configured to be sized at run-time |
template<typename U> spsc_queue(size_type element_count, typename allocator::template rebind< U >::other const & alloc);
spsc_queue(size_type element_count, allocator_arg const & alloc);
spsc_queue
public member functionsbool push(T const & t);
Pushes object t to the ringbuffer.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to push data to the spsc_queue |
Postconditions: |
object will be pushed to the spsc_queue, unless it is full. |
Returns: |
true, if the push operation is successful. |
bool pop();
Pops one object from ringbuffer.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to pop data to the spsc_queue |
Postconditions: |
if ringbuffer is not empty, object will be discarded. |
Returns: |
true, if the pop operation is successful, false if ringbuffer was empty. |
template<typename U> boost::enable_if< typename is_convertible< T, U >::type, bool >::type pop(U & ret);
Pops one object from ringbuffer.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to pop data to the spsc_queue |
Postconditions: |
if ringbuffer is not empty, object will be copied to ret. |
Returns: |
true, if the pop operation is successful, false if ringbuffer was empty. |
size_type push(T const * t, size_type size);
Pushes as many objects from the array t as there is space.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to push data to the spsc_queue |
Returns: |
number of pushed items |
template<size_type size> size_type push(T const (&) t);
Pushes as many objects from the array t as there is space available.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to push data to the spsc_queue |
Returns: |
number of pushed items |
template<typename ConstIterator> ConstIterator push(ConstIterator begin, ConstIterator end);
Pushes as many objects from the range [begin, end) as there is space .
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to push data to the spsc_queue |
Returns: |
iterator to the first element, which has not been pushed |
size_type pop(T * ret, size_type size);
Pops a maximum of size objects from ringbuffer.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to pop data to the spsc_queue |
Returns: |
number of popped items |
template<size_type size> size_type pop(T(&) ret);
Pops a maximum of size objects from spsc_queue
.
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to pop data to the spsc_queue |
Returns: |
number of popped items |
template<typename OutputIterator> boost::disable_if< typename is_convertible< T, OutputIterator >::type, size_type >::type pop(OutputIterator it);
Pops objects to the output iterator it
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only one thread is allowed to pop data to the spsc_queue |
Returns: |
number of popped items |
template<typename Functor> bool consume_one(Functor & f);
consumes one element via a functor
pops one element from the queue and applies the functor on this object
Note | |
---|---|
Thread-safe and non-blocking, if functor is thread-safe and non-blocking |
Returns: |
true, if one element was consumed |
template<typename Functor> bool consume_one(Functor const & f);
consumes one element via a functor
pops one element from the queue and applies the functor on this object
Note | |
---|---|
Thread-safe and non-blocking, if functor is thread-safe and non-blocking |
Returns: |
true, if one element was consumed |
template<typename Functor> size_type consume_all(Functor & f);
consumes all elements via a functor
sequentially pops all elements from the queue and applies the functor on each object
Note | |
---|---|
Thread-safe and non-blocking, if functor is thread-safe and non-blocking |
Returns: |
number of elements that are consumed |
template<typename Functor> size_type consume_all(Functor const & f);
consumes all elements via a functor
sequentially pops all elements from the queue and applies the functor on each object
Note | |
---|---|
Thread-safe and non-blocking, if functor is thread-safe and non-blocking |
Returns: |
number of elements that are consumed |
size_type read_available() const;
get number of elements that are available for read
Note | |
---|---|
Thread-safe and wait-free, should only be called from the consumer thread |
Returns: |
number of available elements that can be popped from the spsc_queue |
size_type write_available() const;
get write space to write elements
Note | |
---|---|
Thread-safe and wait-free, should only be called from the producer thread |
Returns: |
number of elements that can be pushed to the spsc_queue |
const T & front() const;
get reference to element in the front of the queue
Availability of front element can be checked using read_available().
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only a consuming thread is allowed to check front element read_available() > 0. If ringbuffer is empty, it's undefined behaviour to invoke this method. |
Returns: |
reference to the first element in the queue |
T & front();
get reference to element in the front of the queue
Availability of front element can be checked using read_available().
Note | |
---|---|
Thread-safe and wait-free |
Requires: |
only a consuming thread is allowed to check front element read_available() > 0. If ringbuffer is empty, it's undefined behaviour to invoke this method. |
Returns: |
reference to the first element in the queue |
void reset(void);
reset the ringbuffer
Note | |
---|---|
Not thread-safe |