Class Concurrent Queue
Thread-safe queue for multiple producers and multiple consumers.

All Subcl's ConcurrentSuspendableQueue
Defined in <seqan/parallel.h>
Signature template <typename TValue, typename TSpec> class ConcurrentQueue;

Template Parameters

TValue Element type of the queue.
TSpec Tag for further specializing the Concurrent Queue. Default is void.

Interface Function Overview

Detailed Description

The Concurrent Queue is a thread-safe FIFO queue that supports multiple producers and multiple consumers (MPMC). Elements are enqueued via appendValue and dequeued with tryPopFront or popFront. Depending on the expansion tag of appendValue it can grow dynamically or have a fixed size.

The implementation is lock-free and uses a @Class.AllocString@ as ring buffer.

Examples

Simple example for a single producer single consumer (SPSC) dynamic queue.

#include <iostream>
#include <seqan/parallel.h>

using namespace seqan;

int main()
{
    // instantiate an empty Queue
    ConcurrentQueue<unsigned> queue;

    // start two threads
    SEQAN_OMP_PRAGMA(parallel sections num_threads(2))
    {
        SEQAN_OMP_PRAGMA(section)
        {
            for (unsigned i = 9999; i != 0; --i)
                appendValue(queue, i);
        }

        SEQAN_OMP_PRAGMA(section)
        {
            bool equal = true;
            for (unsigned i = 9999; i != 0; --i)
                equal &= (i == popFront(queue));
            std::cout << (equal ? "SUCCESS" : "FAILURE") << std::endl;
        }
    }

    return 0;
}

The output is:

SUCCESS

Interface Functions Detail

void appendValue(queue, val[, expandTag[, parallelTag]);

Enqueue a value to a queue.

Parameters

queue A queue.
val The value to enqueue.
expandTag The overflow strategy. If Generous the queue will be automatically resized if the capacity is exceeded, otherwise the thread spinlocks until the element can be enqueued. Default is the DefaultOverflowImplicit result for the queue type.
parallelTag The concurrency scheme. If multiple threads enqueue values concurrently this tag must be Parallel. The more efficient Serial tag can only be used if one thread calls appendValue at a time. Default is Parallel.

Data Races

Thread safety unknown!

TSize capacity(queue);

Returns the capacity of a queue.

Parameters

queue The queue to query for its capacity.

Returns

TSize Returns the capacity of the queue.

The capacity is the number of elements that can be enqueued at the same time without reallocating memory.

Data Races

Thread safety unknown!

bool empty(queue);

Returns whether a queue is empty.

Parameters

queue The queue to query.

Returns

bool Whether or not the queue is empty.

Data Races

Thread safety unknown!

TSize length(queue);

Returns the size of a queue.

Parameters

queue The queue to query for its size.

Returns

TSize The number of elements in the queue.

Data Races

Thread safety unknown!

void lockReading(queue);

Register a reader.

Parameters

queue The queue to register a reader at.

The destructor of the queue will spinlock until all readers are deregistered.

Data Races

Thread safety unknown!

void lockWriting(queue);

Register a writer.

Parameters

queue The queue to register a writer at.

Data Races

Thread safety unknown!

bool popFront(result, queue[, parallelTag]);

Dequeue a value from a queue.

Parameters

queue A queue.
result The dequeued value. If the queue is empty but writers are available the thread spinlocks until a value becomes available.
parallelTag The concurrency scheme. If multiple threads dequeue values concurrently this tag must be Parallel. The more efficient Serial tag can only be used if one thread calls popFront at a time. Default is Parallel.

Returns

bool Returns true if a value could be dequeued or false if no writer is available, see waitForWriters.

Data Races

Thread safety unknown!

TValue popFront(queue[, parallelTag]);

Dequeue a value from a queue.

Parameters

queue A queue.
parallelTag The concurrency scheme. If multiple threads dequeue values concurrently this tag must be Parallel. The more efficient Serial tag can only be used if one thread calls popFront at a time. Default is Parallel.

Returns

TValue The dequeued value. If the queue is empty the thread spinlocks until a value becomes available.

Data Races

Thread safety unknown!

bool tryPopFront(result, queue[, parallelTag]);

Try to dequeue a value from a queue.

Parameters

queue A queue.
result The dequeued value (if available).
parallelTag The concurrency scheme. If multiple threads dequeue values concurrently this tag must be Parallel. The more efficient Serial tag can only be used if one thread calls popFront at a time. Default is Parallel.

Returns

bool Returns true if a value could be dequeued and false otherwise.

Data Races

Thread safety unknown!

void unlockReading(queue);

Deregister a reader.

Parameters

queue The queue to deregister a reader from.

The destructor of the queue will spinlock until all readers are deregistered.

Data Races

Thread safety unknown!

void unlockWriting(queue);

Deregister a writer.

Parameters

queue The queue to deregister a writer from.

Data Races

Thread safety unknown!

void waitForFirstValue(queue);

Wait for writers to enqueue the first value.

Parameters

queue A queue.

If the values are dequeued with popFront2, this function is a barrier for all readers to wait until all writers are set up completely and should be called before calling popFront2 the first time.

Data Races

Thread safety unknown!

void waitForWriters(queue, writerCount);

Wait for writers to register.

Parameters

queue A queue.
writerCount The minimal required number of registered writers, see lockWriting.

If the values are dequeued with popFront2, this function is a barrier for all writers to set up completely and should be called before calling appendValue the first time.

Data Races

Thread safety unknown!