cppthread 1.1.16
C++ Thread Library
Public Types | Public Member Functions | Private Attributes | List of all members
cppthread::item_with_predicate Class Reference

A runner augmentation allowing for worker threads. More...

Collaboration diagram for cppthread::item_with_predicate:
Collaboration graph
[legend]

Public Types

typedef std::deque< weak_pointer_tdependencies_t
 The type representing the list of dependencies.
 
typedef std::shared_ptr< item_with_predicatepointer_t
 The item_with_predicate shared pointer type.
 
typedef std::weak_ptr< item_with_predicateweak_pointer_t
 The item_with_predicate weak pointer type.
 

Public Member Functions

 item_with_predicate (dependencies_t const &dependencies)
 Initialize the item with a list of dependencies.
 
 item_with_predicate (pointer_t dependency=pointer_t())
 Initialize the item with one dependency.
 
virtual ~item_with_predicate ()
 The destructor of the item with predicate.
 
void add_dependencies (dependencies_t const &dependencies)
 Add a set of dependencies at once.
 
void add_dependency (pointer_t dependency)
 Add an item as a predicate of this item.
 
virtual bool valid_workload () const
 The valid_workload() to test whether we can process this item.
 

Private Attributes

dependencies_t f_dependencies = dependencies_t()
 Set of dependencies.
 
mutex f_mutex = mutex()
 The mutex used to protect the predicate variables.
 
bool f_processing = false
 Whether this workload is being processed.
 

Detailed Description

This class allows you to create a pool of worker threads. This is useful to add/remove work in a fifo object and have any one worker thread pick up the next load as soon as it becomes available. This is pretty much the fastest way to get work done using threads, however, it really only works if you can easily break down the work by chunk.

One pool of worker threads is expected to share one pair of fifo objects. Also. the input and output fifo objects must be of the same type.

To use your pool of threads, all you have to do is add data to the input fifo and grab results from the output fifo. Note that the output fifo of one pool of threads can be the input fifo of another pool of threads.

Definition at line 48 of file item_with_predicate.h.

Member Typedef Documentation

◆ dependencies_t

This type is used to hold the list of dependencies as weak pointers. Once that list is empty (we automatically remove pointers which can't be locked anymore), the predicate is considered true and the this workload can then be worked on by a thread from the pool.

Definition at line 56 of file item_with_predicate.h.

◆ pointer_t

To use an item_with_predicate, we strongly advice that you use a shared pointer. This type defines that shared pointer.

Definition at line 52 of file item_with_predicate.h.

◆ weak_pointer_t

The items are added as dependencies and in that case we add them as weak pointers so when done with a workload, it disappears automatically and the predicate becomes true.

Definition at line 54 of file item_with_predicate.h.

Constructor & Destructor Documentation

◆ item_with_predicate() [1/2]

cppthread::item_with_predicate::item_with_predicate ( pointer_t  dependency = pointer_t())

This constructor initializes the item with one dependency. If you do not yet have the list of dependencies for this item, then you can instead use the add_dependency() and add_dependencies() functions to add them later.

As long as you have an item and its processing didn't start yet, you can add additional dependencies.

Parameters
[in]dependencyThe dependency to add to this item on creation.

Definition at line 91 of file item_with_predicate.cpp.

◆ item_with_predicate() [2/2]

cppthread::item_with_predicate::item_with_predicate ( dependencies_t const &  dependencies)

This constructor initializes the item with a list of dependencies. If you do not yet have the list of dependencies, then you can instead use the add_dependency() or add_dependencies() functions to add dependencies later.

As long as you have an item and its processing didn't start yet, you can add additional dependencies.

Note
Since C++11 we can call this function with a list of items as in:

std::make_shared<item_with_predicate>({ a, b, c, d, ... });

which makes this constructor particularly practical.

Parameters
[in]dependenciesThe dependencies to add to this item.

Definition at line 116 of file item_with_predicate.cpp.

◆ ~item_with_predicate()

cppthread::item_with_predicate::~item_with_predicate ( )
virtual

This function is here because the class is virtual and thus a destructor is always required.

Definition at line 127 of file item_with_predicate.cpp.

Member Function Documentation

◆ add_dependencies()

void cppthread::item_with_predicate::add_dependencies ( dependencies_t const &  dependencies)

This function adds all the dependencies found in the dependencies parameter to this item_with_predicate object. This is equivalent to adding the dependencies one at a time to this item.

Exceptions
cppthread_in_use_errorThis exception is raised if this item was already sent to a thread for processing since by then it's too late, you just can't hope to stop the processing or restart it.
Parameters
[in]dependenciesThe dependencies to add to this item.

Definition at line 183 of file item_with_predicate.cpp.

References f_dependencies, f_mutex, and f_processing.

◆ add_dependency()

void cppthread::item_with_predicate::add_dependency ( pointer_t  item)

This function adds the specified item as a predicate of this item. This means that predicate item needs to be processed before this item gets processed.

The predicate is just another item_with_predicate object. A weak pointer is kept by this item_with_predicate object. When the thread handling the predicate is done, the shared pointer will be released meaning that the weak pointer that this item holds will be released too. When all the dependencies added here are released, the valid_workload() function returns true and this very workload item gets processed.

Exceptions
cppthread_in_use_errorThis exception is raised if this item was already sent to a thread for processing since by then it's too late, you just can't hope to stop the processing or restart it.
Todo:
See whether we could make the predicate any kind of objects with a template?
Parameters
[in]itemA predicate item.

Definition at line 157 of file item_with_predicate.cpp.

References f_dependencies, f_mutex, and f_processing.

◆ valid_workload()

bool cppthread::item_with_predicate::valid_workload ( ) const
virtual

When working with a thread pool, you add workload items to the FIFO and they get executed in order unless you have a valid_workload() function. In that case you have to run the process of an item added to the FIFO only if:

If you want additional tests, you can overload the function since it's a virtual function.

Warning
A side effect of calling this function is to mark the item as being processed. At that point, further adding of dependencies is not possible.
Returns
true if the item is ready to be processed (i.e. all of its dependencies were processed).

Definition at line 217 of file item_with_predicate.cpp.

References f_dependencies, f_mutex, and f_processing.

Member Data Documentation

◆ f_dependencies

cppthread::item_with_predicate::f_dependencies = dependencies_t()
mutableprivate

This parameter holds a set of dependencies, which is a set of other items which have to be fully processed before this item can be processed.

The fifo::pop_front() function calls the valid_workload() to know whether the item has dependencies. It becomes true only once all the dependencies were processed.

The set uses weak pointers and detects that another item processing is done because it gets released. In your code, you must make sure that all the item allocations you've made go out of scope by the time you start the execution, otherwise valid_workload() will return false forever.

Definition at line 68 of file item_with_predicate.h.

Referenced by add_dependencies(), add_dependency(), and valid_workload().

◆ f_mutex

cppthread::item_with_predicate::f_mutex = mutex()
mutableprivate

This mutex is used to make sure that functions that modify the variable members do so safely (i.e. only one thread at a time).

Definition at line 67 of file item_with_predicate.h.

Referenced by add_dependencies(), add_dependency(), and valid_workload().

◆ f_processing

cppthread::item_with_predicate::f_processing = false
mutableprivate

If this workload predicate is true, then it can be processed and thus this flag becomes true. At that point, the add_dependency() and add_dependencies() do not work anymore (if you call them, they raise an exception).

Definition at line 69 of file item_with_predicate.h.

Referenced by add_dependencies(), add_dependency(), and valid_workload().


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

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.