Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This version of Boost is under active development. You are currently in the develop branch. The current version is 1.91.0.
boost::lockfree::bounded_ticket_queue
// In header: <boost/lockfree/bounded_ticket_queue.hpp> template<typename T, typename... Options> class bounded_ticket_queue { public: // types typedef T value_type; typedef implementation_defined::allocator allocator; typedef implementation_defined::size_type size_type; // public member functions bool is_lock_free() const; bounded_ticket_queue(); template<typename Enabler = std::enable_if< !has_capacity > > explicit bounded_ticket_queue(size_type); template<typename Enabler = std::enable_if< !has_capacity > > bounded_ticket_queue(size_type, allocator const &); bounded_ticket_queue(const bounded_ticket_queue &) = delete; bounded_ticket_queue & operator=(const bounded_ticket_queue &) = delete; bounded_ticket_queue(bounded_ticket_queue &&) = delete; bounded_ticket_queue & operator=(bounded_ticket_queue &&) = delete; ~bounded_ticket_queue(); bool empty() const; size_type capacity() const; bool push(const T &); bool push(T &&); bool pop(T &); template<typename U, typename Enabler = typename std::enable_if< std::is_constructible< U, T&& >::value >::type> bool pop(U &); std::optional< T > pop(uses_optional_t); template<typename U> std::optional< U > pop(uses_optional_t); template<typename Functor> bool consume_one(Functor &&); template<typename Functor> size_t consume_all(Functor &&); };
Bounded ticket queue based on Dmitry Vyukov's bounded MPMC queue (the "Dyukov turnstile") (reference).
The queue uses a fixed-size ring buffer of cells, each protected by a monotonically increasing ticket (sequence number). Producers and consumers coordinate solely by advancing this ticket.
The data structure is linearizable.
Caveats.
Multi-producer push is not lock-free. A concurrent producer that has claimed a slot via CAS but is then suspended can block all other producers once the ring buffer wraps around to that slot. In practice preemption is brief, but hard real-time systems should prefer a single-producer configuration.
Multi-consumer pop is not lock-free. Symmetric stall risk as multi-producer push. Prefer single_consumer<true> for hard real-time.
Unfairness. The CAS-based slot reservation provides no FIFO or fairness guarantee.
Policies.
boost::lockfree::capacity (optional):
Sets the queue capacity at compile time. Implies a static storage buffer and precludes specifying an allocator.
boost::lockfree::allocator (default std::allocator<void>).
Allocator used for the cell storage. Only valid when the capacity is specified at run time.
boost::lockfree::single_producer (default false):
If true, only one thread calls push. Push becomes wait-free.
boost::lockfree::single_consumer (default false):
If true, only one thread calls pop. Pop becomes wait-free.
Requirements.
T must be copy- or move-constructible, depending on which push overload is used.
T must be move-constructible and move-assignable.
bounded_ticket_queue public member functionsbool is_lock_free() const;
With single-producer and single-consumer the queue is wait-free (no CAS used). For multi-consumer or multi-producer configurations only the atomic positions used with CAS are checked.
Returns: |
true if the implementation is lock-free. |
bounded_ticket_queue();
Construct a queue with compile-time capacity.
Storage is allocated in a static buffer; no heap allocation is performed.
Requires: |
Must specify a |
template<typename Enabler = std::enable_if< !has_capacity > > explicit bounded_ticket_queue(size_type n);
Construct a queue with runtime capacity.
Parameters: |
|
||
Requires: |
Must not specify a |
template<typename Enabler = std::enable_if< !has_capacity > > bounded_ticket_queue(size_type n, allocator const & alloc);
Construct a queue with runtime capacity and custom allocator.
Parameters: |
|
||||
Requires: |
Must not specify a |
bounded_ticket_queue(const bounded_ticket_queue &) = delete;
bounded_ticket_queue & operator=(const bounded_ticket_queue &) = delete;
bounded_ticket_queue(bounded_ticket_queue &&) = delete;
bounded_ticket_queue & operator=(bounded_ticket_queue &&) = delete;
~bounded_ticket_queue();
Destroys the queue.
bool empty() const;
Check whether the queue is empty.
![]() |
Note |
|---|---|
The result is only accurate when no other thread modifies the queue concurrently. |
Returns: |
true if the queue is empty, false otherwise. |
size_type capacity() const;
Returns: |
the capacity of the queue. |
bool push(const T & t);
Pushes a value to the queue.
![]() |
Note |
|---|---|
Thread-safe. Multiple producers may call push concurrently. Never allocates memory. |
Returns: |
true if the value was pushed, false if the queue is full. |
bool push(T && t);
bool pop(T & ret);
Pops an element from the queue.
Returns: |
true if an element was popped, false if the queue was empty. |
template<typename U, typename Enabler = typename std::enable_if< std::is_constructible< U, T&& >::value >::type> bool pop(U & ret);
Pops an element from the queue.
Template Parameters: |
|
||
Returns: |
true if an element was popped, false if the queue was empty. |
std::optional< T > pop(uses_optional_t);
Pops an element, returning a std::optional<T>.
Returns: |
std::optional containing the value on success, std::nullopt if the queue is empty. |
template<typename U> std::optional< U > pop(uses_optional_t);
Pops an element, returning a std::optional.
Template Parameters: |
|
||
Returns: |
std::optional<U> containing the value on success, std::nullopt if the queue is empty. |
template<typename Functor> bool consume_one(Functor && f);
Consumes one element via a functor.
Moves one element out of the slot, passes the resulting rvalue to the functor, and releases the slot for reuse once the functor returns.
Returns: |
true if an element was consumed. |
template<typename Functor> size_t consume_all(Functor && f);
Consumes all elements via a functor.
Sequentially pops all elements and applies the functor to each.
Returns: |
the number of elements consumed. |