A first-in first-out thread-safe item queue. More...
#include "thread_queue.h"
Classes | |
class | Reader |
This class is used to register a reader with the queue. More... | |
class | Writer |
This class is used to register a writer with the queue. More... | |
Public Member Functions | |
Queue (const std::string &description="unnamed", size_t buffer_size=128) | |
Construct a Queue of items of type T . More... | |
Queue (const Queue &)=delete | |
Queue (Queue &&)=default | |
Queue & | operator= (const Queue &)=delete |
Queue & | operator= (Queue &&)=default |
~Queue () | |
void | status () |
Print out a status report for debugging purposes. More... | |
A first-in first-out thread-safe item queue.
This class implements a thread-safe means of pushing data items into a queue, so that they can each be processed in one or more separate threads.
Thread::Queue has somewhat unusual usage, which consists of the following steps:
false
from the next write attempt.false
from the next read attempt.The additional member classes are designed to be used in conjunction with the MRtrix multi-threading interface. In this system, each thread corresponds to an instance of a functor class, and its execute() method is the function that will be run within the thread (see Thread::Exec for details). For this reason:
The Queue class performs all memory management for the items in the queue. For this reason, the items are accessed via the Writer::Item & Reader::Item classes. This allows items to be recycled once they have been processed, reducing overheads associated with memory allocation/deallocation.
The use of Thread::Queue is best illustrated with an example:
The motivation for the use of additional member classes to perform the actual process of writing and reading to and from the queue is related to the need to keep track of the number of processes currently using the queue. This is essential to ensure that threads are notified when the queue is closed. This happens either when all readers have finished reading; or when all writers have finished writing and no items are left in the queue. This is complicated by the need to ensure that the various operations are called in the right order to avoid deadlocks.
There are essentially 4 operations that need to take place:
For proper multi-threaded operations, these operations must take place in the order above. Moreover, each operation must be completed for all users of the queue before any of them can perform the next operation. The use of additional member classes ensures that threads have to register their intention to read or write from the queue, and that they unregister from the queue once their processing is done.
While this could have been achieved simply with the appropriate member functions (i.e. register(), unregister(), read() & write() methods in the main Queue class), this places a huge burden on the developer to get it right. Using these member functions reduces the chance of coding errors, and in fact reduces the total amount of code that needs to be written to use the Queue in a safe manner.
The Item classes additionally simplify the memory management of the items in the queue, by preventing direct access to the underlying pointers, and ensuring the Queue itself is responsible for all allocation and deallocation of items as needed.
Definition at line 334 of file thread_queue.h.
|
inline |
Construct a Queue of items of type T
.
description | a string identifying the queue for degugging purposes |
buffer_size | the maximum number of items that can be pushed onto the queue before blocking. If a thread attempts to push more data onto the queue when the queue already contains this number of items, the thread will block until at least one item has been popped. By default, the buffer size is MRTRIX_QUEUE_DEFAULT_CAPACITY items. |
Definition at line 344 of file thread_queue.h.
|
delete |
|
default |
|
inline |
Definition at line 361 of file thread_queue.h.
|
delete |
|
default |
|
inline |
Print out a status report for debugging purposes.
Definition at line 516 of file thread_queue.h.