c++-gtk-utils
Namespaces | Classes | Enumerations | Functions
Cgu::Thread Namespace Reference

Namespaces

 FutureHelper
 
 TaskManagerHelper
 

Classes

struct  FutureThreadError
 
struct  FutureWhenError
 
class  Future
 A class representing a pthread thread which will provide a value. More...
 
struct  CondError
 
struct  MutexError
 
struct  RecMutexError
 
class  Mutex
 A wrapper class for pthread mutexes. More...
 
class  Cond
 A wrapper class for pthread condition variables. More...
 
class  RecMutex
 A wrapper class for pthread mutexes which provides a recursive mutex. More...
 
class  GrecmutexLock
 A scoped locking class for exception safe locking of GStaticRecMutex objects. More...
 
struct  ParallelError
 
struct  RWLockError
 
class  RWLock
 A wrapper class for pthread read-write locks. More...
 
struct  TaskError
 
class  TaskManager
 A thread-pool class for managing tasks in multi-threaded programs. More...
 
class  Thread
 A class representing a pthread thread. More...
 
class  JoinableHandle
 A class wrapping a Thread::Thread object representing a joinable thread. More...
 
class  CancelBlock
 A class enabling the cancellation state of a thread to be controlled. More...
 
class  Exit
 A class which can be thrown to terminate the throwing thread. More...
 

Enumerations

enum  Locked { locked }
 
enum  DeferLock { defer }
 

Functions

template<class Obj , class Ret , class... Params, class... Args>
Cgu::IntrusivePtr
< Cgu::Thread::Future< Ret > > 
make_future (Obj &obj, Ret(Obj::*func)(Params...), Args &&...args)
 
template<class Obj , class Ret , class... Params, class... Args>
Cgu::IntrusivePtr
< Cgu::Thread::Future< Ret > > 
make_future (const Obj &obj, Ret(Obj::*func)(Params...) const, Args &&...args)
 
template<class Ret , class... Params, class... Args>
Cgu::IntrusivePtr
< Cgu::Thread::Future< Ret > > 
make_future (Ret(*func)(Params...), Args &&...args)
 
template<class Ret , class Func >
Cgu::IntrusivePtr
< Cgu::Thread::Future< Ret > > 
make_future (Func &&func)
 
template<class Iterator , class Func >
void parallel_for_each (TaskManager &tm, Iterator first, Iterator last, Func &&func)
 
template<class SourceIterator , class DestIterator , class Func >
void parallel_transform (TaskManager &tm, SourceIterator first, SourceIterator last, DestIterator dest, Func &&func)
 
template<class SourceIterator1 , class SourceIterator2 , class DestIterator , class Func >
void parallel_transform (TaskManager &tm, SourceIterator1 first1, SourceIterator1 last1, SourceIterator2 first2, DestIterator dest, Func &&func)
 

Enumeration Type Documentation

Enumerator
defer 
Enumerator
locked 

Function Documentation

template<class Obj , class Ret , class... Params, class... Args>
Cgu::IntrusivePtr<Cgu::Thread::Future<Ret> > Cgu::Thread::make_future ( Obj &  obj,
Ret(Obj::*)(Params...)  func,
Args &&...  args 
)
Deprecated:

DEPRECATED. Use the version of make_future() which takes a callable object.

A convenience helper function which calls Cgu::Thread::Future::make() to obtain a Future object without the need to specify the return value of the function represented by the new object: that is deduced from the signature of that function. This is useful shorthand when also employed with the C++11 'auto' keyword.

Exceptions
std::bad_allocIt might throw std::bad_alloc if memory is exhausted and the system throws in that case. (This exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option: instead glib will terminate the program if it is unable to obtain memory from the operating system.)
Cgu::Thread::MutexErrorIt might throw Cgu::Thread::MutexError if initialisation of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)
Cgu::Thread::CondErrorIt might throw Cgu::Thread::CondError if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.)
Note
This method will also throw if the copy or move constructor of a bound argument throws, or the default constructor of the return value type of the function represented by the new object throws.

Since 2.0.4

template<class Obj , class Ret , class... Params, class... Args>
Cgu::IntrusivePtr<Cgu::Thread::Future<Ret> > Cgu::Thread::make_future ( const Obj &  obj,
Ret(Obj::*)(Params...) const  func,
Args &&...  args 
)
Deprecated:

DEPRECATED. Use the version of make_future() which takes a callable object.

A convenience helper function which calls Cgu::Thread::Future::make() to obtain a Future object without the need to specify the return value of the function represented by the new object: that is deduced from the signature of that function. This is useful shorthand when also employed with the C++11 'auto' keyword.

Exceptions
std::bad_allocIt might throw std::bad_alloc if memory is exhausted and the system throws in that case. (This exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option: instead glib will terminate the program if it is unable to obtain memory from the operating system.)
Cgu::Thread::MutexErrorIt might throw Cgu::Thread::MutexError if initialisation of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)
Cgu::Thread::CondErrorIt might throw Cgu::Thread::CondError if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.)
Note
This method will also throw if the copy or move constructor of a bound argument throws, or the default constructor of the return value type of the function represented by the new object throws.

Since 2.0.4

template<class Ret , class... Params, class... Args>
Cgu::IntrusivePtr<Cgu::Thread::Future<Ret> > Cgu::Thread::make_future ( Ret(*)(Params...)  func,
Args &&...  args 
)
Deprecated:

DEPRECATED. Use the version of make_future() which takes a callable object.

A convenience helper function which calls Cgu::Thread::Future::make() to obtain a Future object without the need to specify the return value of the function represented by the new object: that is deduced from the signature of that function. This is useful shorthand when also employed with the C++11 'auto' keyword.

Exceptions
std::bad_allocIt might throw std::bad_alloc if memory is exhausted and the system throws in that case. (This exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option: instead glib will terminate the program if it is unable to obtain memory from the operating system.)
Cgu::Thread::MutexErrorIt might throw Cgu::Thread::MutexError if initialisation of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)
Cgu::Thread::CondErrorIt might throw Cgu::Thread::CondError if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.)
Note
This method will also throw if the copy or move constructor of a bound argument throws, or the default constructor of the return value type of the function represented by the new object throws.

Since 2.0.4

template<class Ret , class Func >
Cgu::IntrusivePtr<Cgu::Thread::Future<Ret> > Cgu::Thread::make_future ( Func &&  func)

A convenience helper function which calls Cgu::Thread::Future::make() to obtain a Future without the need to specify the return value of the callable object to be represented by it: that is deduced. This is useful shorthand when also employed with the C++11 'auto' keyword.

Parameters
funcA callable object, such as formed by a lambda expression or the result of std::bind. It must be fully bound (that is, its must take no arguments when called). It should return a value (it cannot return void).
Exceptions
std::bad_allocIt might throw std::bad_alloc if memory is exhausted and the system throws in that case. (This exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option: instead glib will terminate the program if it is unable to obtain memory from the operating system.)
Cgu::Thread::MutexErrorIt might throw Cgu::Thread::MutexError if initialisation of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)
Cgu::Thread::CondErrorIt might throw Cgu::Thread::CondError if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.)
Note
1. This method will also throw if the copy or move constructor of the callable object passed as an argument throws, or the default constructor of the return value type of the function represented by the new object throws.
2. If the callable object passed as an argument has both const and non-const operator()() methods, the non-const version will be called even if the callable object passed is a const object.

Since 2.0.14

template<class Iterator , class Func >
void Cgu::Thread::parallel_for_each ( TaskManager &  tm,
Iterator  first,
Iterator  last,
Func &&  func 
)

#include <c++-gtk-utils/parallel.h>

This function applies a callable object to each element of a container in the range ['first', 'last'), by executing each such application as a task of a Thread::TaskManager object. Tasks are added to the Thread::TaskManager object in the order in which the respective elements appear in the container, but no other ordering arises, and they will execute in parallel to the extent that the Thread::TaskManager object has sufficient threads available to do so.

Apart from that, and that this function returns void, it does the same as std::for_each(). It can mutate container elements if the callable object takes its argument by non-const reference. It will not return until the callable object has been applied to all of the elements in the range ['first', 'last').

This function can be called by a task running on the same TaskManager object.

Parameters
tmThe Thread::TaskManager object on which the tasks will run.
firstThe beginning of the range to which 'func' is to be applied.
lastOne past the last element to which 'func' is to be applied.
funcA callable object to be applied to each element in the range ['first', 'last'), such as formed by a lambda expression or the result of std::bind. It should take a single unbound argument of the value type of the container to which 'first' and 'last' relate or a const or non-const reference to that type. Any return value is discarded. If an exception propagates from 'func', the exception will be consumed while the for each loop is running, and an attempt will still be made to apply 'func' to all remaining elements in the range ['first', 'last'), and only after that attempt has completed will the exception Cgu::Thread::ParallelError be thrown.
Exceptions
std::bad_allocThis exception will be thrown if memory is exhausted and the system throws in that case. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion). If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function, but subsequent ones will not.
Cgu::Thread::TaskErrorThis exception will be thrown if stop_all() has previously been called on the Thread::TaskManager object, or if another thread calls stop_all() after this method is called but before it has returned. It will also be thrown if the Thread::TaskManager object's is_error() method would return true because its internal thread pool loop implementation has thrown std::bad_alloc, or a thread has failed to start correctly. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion, but there may be some specialized cases where the return value of is_error() is useful.) If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function.
Cgu::Thread::ParallelErrorThis exception will be thrown if an exception propagates from the 'func' callable object when it executes on being applied to one or more elements of the container. Such an exception will not stop an attempt being made to apply 'func' (successfully or unsuccessfully) to all elements in the range ['first', 'last'). Cgu::Thread::ParallelError will be thrown after such attempted application has finished.
Cgu::Thread::MutexErrorThis exception will be thrown if initialization of a mutex used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) If this exception is thrown, no tasks will start.
Cgu::Thread::CondErrorThis exception will be thrown if initialization of a condition variable used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) If this exception is thrown, no tasks will start.
Note
An exception might also be thrown if the copy or move constructor of the 'func' callable objects throws. If such an exception is thrown, no tasks will start.

Since 2.0.19/2.2.2

template<class SourceIterator , class DestIterator , class Func >
void Cgu::Thread::parallel_transform ( TaskManager &  tm,
SourceIterator  first,
SourceIterator  last,
DestIterator  dest,
Func &&  func 
)

#include <c++-gtk-utils/parallel.h>

This function maps over a container in the range ['first', 'last'), applying a unary callable object to each element of the container in that range and storing the result in the destination range, by executing each such application as a task of a Thread::TaskManager object. Tasks are added to the Thread::TaskManager object in the order in which the respective elements appear in the source container, but no other ordering arises, and they will execute in parallel to the extent that the Thread::TaskManager object has sufficient threads available to do so.

Apart from that, this function does the same as the version of std::transform() taking a unary function. It will not return until the callable object has been applied to all of the elements in the range ['first', 'last').

This function can be called by a task running on the same TaskManager object (a result can therefore be delivered asynchronously by calling this function in a task created by the make_task_when(), make_task_compose() or make_task_when_full() Thread::TaskManager methods). A task can carry out a map-reduce operation by passing the result of calling this function to std::accumulate() to perform a fold-left or fold-right on that result.

A separate overload of this function takes a binary callable object.

Here is a trivial example of a map-reduce operation which maps over a vector by multiplying each element by 2 in separate tasks, and then folds-left using std::accumulate() (std::accumulate() can fold using any callable object, but in this example the default of addition is used):

using namespace Cgu;
std::vector<int> v{1, 2, 3, 4, 5};
v.begin(),
v.end(),
v.begin(),
[] (int elt) {return elt * 2;});
// res will be equal to 30
int res = std::accumulate(v.begin(), v.end(), 0);
Parameters
tmThe Thread::TaskManager object on which the tasks will run.
firstThe beginning of the range to which 'func' is to be applied.
lastOne past the last element to which 'func' is to be applied.
destThe beginning of the range to which the result of applying 'func' to the elements in the range ['first', 'last') is to be stored. As in the case of std::transform, this can overlap with or be the same as the source range. It may also be an inserter iterator.
funcA callable object to be applied to each element in the range ['first', 'last'), such as formed by a lambda expression or the result of std::bind. It should take a single unbound argument of the value type of the container to which 'first' and 'last' relate or a const or non-const reference to that type. If an exception propagates from 'func', the exception will be consumed while the transform loop is running, and an attempt will still be made to apply 'func' to all remaining elements in the range ['first', 'last'), and only after that attempt has completed will the exception Cgu::Thread::ParallelError be thrown.
Exceptions
std::bad_allocThis exception will be thrown if memory is exhausted and the system throws in that case. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion). If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function, but subsequent ones will not.
Cgu::Thread::TaskErrorThis exception will be thrown if stop_all() has previously been called on the Thread::TaskManager object, or if another thread calls stop_all() after this method is called but before it has returned. It will also be thrown if the Thread::TaskManager object's is_error() method would return true because its internal thread pool loop implementation has thrown std::bad_alloc, or a thread has failed to start correctly. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion, but there may be some specialized cases where the return value of is_error() is useful.) If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function.
Cgu::Thread::ParallelErrorThis exception will be thrown if an exception propagates from the 'func' callable object when it executes on being applied to one or more elements of the source container. Such an exception will not stop an attempt being made to apply 'func' (successfully or unsuccessfully) to all elements in the range ['first', 'last'). Cgu::Thread::ParallelError will be thrown after such attempted application has finished.
Cgu::Thread::MutexErrorThis exception will be thrown if initialization of a mutex used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) If this exception is thrown, no tasks will start.
Cgu::Thread::CondErrorThis exception will be thrown if initialization of a condition variable used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) If this exception is thrown, no tasks will start.
Note
An exception might also be thrown if the copy or move constructor of the 'func' callable objects throws. If such an exception is thrown, no tasks will start.

Since 2.0.19/2.2.2

template<class SourceIterator1 , class SourceIterator2 , class DestIterator , class Func >
void Cgu::Thread::parallel_transform ( TaskManager &  tm,
SourceIterator1  first1,
SourceIterator1  last1,
SourceIterator2  first2,
DestIterator  dest,
Func &&  func 
)

#include <c++-gtk-utils/parallel.h>

This function maps over two containers, one in the range ['first1', 'last1') and the other beginning at 'first2', applying a binary callable object to each element of the containers in those ranges and storing the result in the destination range, by executing each such application as a task of a Thread::TaskManager object. Tasks are added to the Thread::TaskManager object in the order in which the respective elements appear in the source containers, but no other ordering arises, and they will execute in parallel to the extent that the Thread::TaskManager object has sufficient threads available to do so.

Apart from that, this function does the same as the version of std::transform() taking a binary function. It will not return until the callable object has been applied to all of the elements in the source ranges.

This function can be called by a task running on the same TaskManager object (a result can therefore be delivered asynchronously by calling this function in a task created by the make_task_when(), make_task_compose() or make_task_when_full() Thread::TaskManager methods). A task can carry out a map-reduce operation by passing the result of calling this function to std::accumulate() to perform a fold-left or fold-right on that result.

A separate overload of this function takes a unary callable object.

Here is a trivial example of a map-reduce operation which maps over two vectors by adding respective elements of the vectors in separate tasks, and then folds-left using std::accumulate() (std::accumulate() can fold using any callable object, but in this example the default of addition is used):

using namespace Cgu;
std::vector<int> v1{2, 4, 6, 8, 10};
std::vector<int> v2{10, 20, 30, 40, 50};
std::vector<int> v3;
v1.begin(),
v1.end(),
v2.begin(),
std::back_inserter(v3),
std::plus<int>());
// res will be equal to 180
int res = std::accumulate(v3.begin(), v3.end(), 0);
Parameters
tmThe Thread::TaskManager object on which the tasks will run.
first1The beginning of the range which is to be passed as the first argument of 'func'.
last1One past the last element of the range which is to be passed as the first argument of 'func'.
first2The beginning of the range which is to be passed as the second argument of 'func'.
destThe beginning of the range to which the result of applying 'func' to the elements in the source ranges is to be stored. As in the case of std::transform, this can overlap with or be the same as one of the source ranges. It may also be an inserter iterator.
funcA binary callable object to be applied to each element in the source ranges, such as formed by a lambda expression or the result of std::bind. It should take two unbound arguments of the value types of the containers to which 'first1' and 'first2' relate or const or non-const references to those types. If an exception propagates from 'func', the exception will be consumed while the transform loop is running, and an attempt will still be made to apply 'func' to all remaining elements of the source ranges, and only after that attempt has completed will the exception Cgu::Thread::ParallelError be thrown.
Exceptions
std::bad_allocThis exception will be thrown if memory is exhausted and the system throws in that case. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion). If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function, but subsequent ones will not.
Cgu::Thread::TaskErrorThis exception will be thrown if stop_all() has previously been called on the Thread::TaskManager object, or if another thread calls stop_all() after this method is called but before it has returned. It will also be thrown if the Thread::TaskManager object's is_error() method would return true because its internal thread pool loop implementation has thrown std::bad_alloc, or a thread has failed to start correctly. (On systems with over-commit/lazy-commit combined with virtual memory (swap), it is rarely useful to check for memory exhaustion, but there may be some specialized cases where the return value of is_error() is useful.) If this exception is thrown, some tasks may nonetheless have already started by virtue of the call to this function.
Cgu::Thread::ParallelErrorThis exception will be thrown if an exception propagates from the 'func' callable object when it executes on being applied to one or more elements of the source ranges. Such an exception will not stop an attempt being made to apply 'func' (successfully or unsuccessfully) to all elements in the source ranges. Cgu::Thread::ParallelError will be thrown after such attempted application has finished.
Cgu::Thread::MutexErrorThis exception will be thrown if initialization of a mutex used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) If this exception is thrown, no tasks will start.
Cgu::Thread::CondErrorThis exception will be thrown if initialization of a condition variable used by this function fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) If this exception is thrown, no tasks will start.
Note
An exception might also be thrown if the copy or move constructor of the 'func' callable objects throws. If such an exception is thrown, no tasks will start.

Since 2.0.19/2.2.2