libkvikio  24.02.00
Public Member Functions | Public Attributes | List of all members
kvikio::third_party::thread_pool Class Reference

A C++17 thread pool class. The user submits tasks to be executed into a queue. Whenever a thread becomes available, it pops a task from the queue and executes it. Each task is automatically assigned a future, which can be used to wait for the task to finish executing and/or obtain its eventual return value. More...

#include <thread_pool.hpp>

Public Member Functions

 thread_pool (const ui32 &_thread_count=std::thread::hardware_concurrency())
 Construct a new thread pool. More...
 
 ~thread_pool ()
 Destruct the thread pool. Waits for all tasks to complete, then destroys all threads. Note that if the variable paused is set to true, then any tasks still in the queue will never be executed.
 
ui64 get_tasks_queued () const
 Get the number of tasks currently waiting in the queue to be executed by the threads. More...
 
ui32 get_tasks_running () const
 Get the number of tasks currently being executed by the threads. More...
 
ui32 get_tasks_total () const
 Get the total number of unfinished tasks - either still in the queue, or running in a thread. More...
 
ui32 get_thread_count () const
 Get the number of threads in the pool. More...
 
template<typename T1 , typename T2 , typename F >
void parallelize_loop (const T1 &first_index, const T2 &index_after_last, const F &loop, ui32 num_blocks=0)
 Parallelize a loop by splitting it into blocks, submitting each block separately to the thread pool, and waiting for all blocks to finish executing. The user supplies a loop function, which will be called once per block and should iterate over the block's range. More...
 
template<typename F >
void push_task (const F &task)
 Push a function with no arguments or return value into the task queue. More...
 
template<typename F , typename... A>
void push_task (const F &task, const A &... args)
 Push a function with arguments, but no return value, into the task queue. More...
 
void reset (const ui32 &_thread_count=std::thread::hardware_concurrency())
 Reset the number of threads in the pool. Waits for all currently running tasks to be completed, then destroys all threads in the pool and creates a new thread pool with the new number of threads. Any tasks that were waiting in the queue before the pool was reset will then be executed by the new threads. If the pool was paused before resetting it, the new pool will be paused as well. More...
 
template<typename F , typename... A, typename = std::enable_if_t< std::is_void_v<std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>>>>
std::future< bool > submit (const F &task, const A &... args)
 Submit a function with zero or more arguments and no return value into the task queue, and get an std::future<bool> that will be set to true upon completion of the task. More...
 
template<typename F , typename... A, typename R = std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>, typename = std::enable_if_t<!std::is_void_v<R>>>
std::future< R > submit (const F &task, const A &... args)
 Submit a function with zero or more arguments and a return value into the task queue, and get a future for its eventual returned value. More...
 
void wait_for_tasks ()
 Wait for tasks to be completed. Normally, this function waits for all tasks, both those that are currently running in the threads and those that are still waiting in the queue. However, if the variable paused is set to true, this function only waits for the currently running tasks (otherwise it would wait forever). To wait for a specific task, use submit() instead, and call the wait() member function of the generated future.
 

Public Attributes

std::atomic< bool > paused = false
 An atomic variable indicating to the workers to pause. When set to true, the workers temporarily stop popping new tasks out of the queue, although any tasks already executed will keep running until they are done. Set to false again to resume popping tasks.
 
ui32 sleep_duration = 1000
 The duration, in microseconds, that the worker function should sleep for when it cannot find any tasks in the queue. If set to 0, then instead of sleeping, the worker function will execute std::this_thread::yield() if there are no tasks in the queue. The default value is 1000.
 

Detailed Description

A C++17 thread pool class. The user submits tasks to be executed into a queue. Whenever a thread becomes available, it pops a task from the queue and executes it. Each task is automatically assigned a future, which can be used to wait for the task to finish executing and/or obtain its eventual return value.

Definition at line 54 of file thread_pool.hpp.

Constructor & Destructor Documentation

◆ thread_pool()

kvikio::third_party::thread_pool::thread_pool ( const ui32 &  _thread_count = std::thread::hardware_concurrency())
inline

Construct a new thread pool.

Parameters
_thread_countThe number of threads to use. The default value is the total number of hardware threads available, as reported by the implementation. With a hyperthreaded CPU, this will be twice the number of CPU cores. If the argument is zero, the default value will be used instead.

Definition at line 71 of file thread_pool.hpp.

Member Function Documentation

◆ get_tasks_queued()

ui64 kvikio::third_party::thread_pool::get_tasks_queued ( ) const
inline

Get the number of tasks currently waiting in the queue to be executed by the threads.

Returns
The number of queued tasks.

Definition at line 99 of file thread_pool.hpp.

◆ get_tasks_running()

ui32 kvikio::third_party::thread_pool::get_tasks_running ( ) const
inline

Get the number of tasks currently being executed by the threads.

Returns
The number of running tasks.

Definition at line 110 of file thread_pool.hpp.

◆ get_tasks_total()

ui32 kvikio::third_party::thread_pool::get_tasks_total ( ) const
inline

Get the total number of unfinished tasks - either still in the queue, or running in a thread.

Returns
The total number of tasks.

Definition at line 118 of file thread_pool.hpp.

◆ get_thread_count()

ui32 kvikio::third_party::thread_pool::get_thread_count ( ) const
inline

Get the number of threads in the pool.

Returns
The number of threads.

Definition at line 125 of file thread_pool.hpp.

◆ parallelize_loop()

template<typename T1 , typename T2 , typename F >
void kvikio::third_party::thread_pool::parallelize_loop ( const T1 &  first_index,
const T2 &  index_after_last,
const F &  loop,
ui32  num_blocks = 0 
)
inline

Parallelize a loop by splitting it into blocks, submitting each block separately to the thread pool, and waiting for all blocks to finish executing. The user supplies a loop function, which will be called once per block and should iterate over the block's range.

Template Parameters
T1The type of the first index in the loop. Should be a signed or unsigned integer.
T2The type of the index after the last index in the loop. Should be a signed or unsigned integer. If T1 is not the same as T2, a common type will be automatically inferred.
FThe type of the function to loop through.
Parameters
first_indexThe first index in the loop.
index_after_lastThe index after the last index in the loop. The loop will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to "for (T i = first_index; i < index_after_last; i++)". Note that if first_index == index_after_last, the function will terminate without doing anything.
loopThe function to loop through. Will be called once per block. Should take exactly two arguments: the first index in the block and the index after the last index in the block. loop(start, end) should typically involve a loop of the form "for (T i = start; i < end; i++)".
num_blocksThe maximum number of blocks to split the loop into. The default is to use the number of threads in the pool.

Definition at line 148 of file thread_pool.hpp.

◆ push_task() [1/2]

template<typename F >
void kvikio::third_party::thread_pool::push_task ( const F &  task)
inline

Push a function with no arguments or return value into the task queue.

Template Parameters
FThe type of the function.
Parameters
taskThe function to push.

Definition at line 193 of file thread_pool.hpp.

◆ push_task() [2/2]

template<typename F , typename... A>
void kvikio::third_party::thread_pool::push_task ( const F &  task,
const A &...  args 
)
inline

Push a function with arguments, but no return value, into the task queue.

The function is wrapped inside a lambda in order to hide the arguments, as the tasks in the queue must be of type std::function<void()>, so they cannot have any arguments or return value. If no arguments are provided, the other overload will be used, in order to avoid the (slight) overhead of using a lambda.

Template Parameters
FThe type of the function.
AThe types of the arguments.
Parameters
taskThe function to push.
argsThe arguments to pass to the function.

Definition at line 215 of file thread_pool.hpp.

◆ reset()

void kvikio::third_party::thread_pool::reset ( const ui32 &  _thread_count = std::thread::hardware_concurrency())
inline

Reset the number of threads in the pool. Waits for all currently running tasks to be completed, then destroys all threads in the pool and creates a new thread pool with the new number of threads. Any tasks that were waiting in the queue before the pool was reset will then be executed by the new threads. If the pool was paused before resetting it, the new pool will be paused as well.

Parameters
_thread_countThe number of threads to use. The default value is the total number of hardware threads available, as reported by the implementation. With a hyperthreaded CPU, this will be twice the number of CPU cores. If the argument is zero, the default value will be used instead.

Definition at line 232 of file thread_pool.hpp.

◆ submit() [1/2]

template<typename F , typename... A, typename = std::enable_if_t< std::is_void_v<std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>>>>
std::future<bool> kvikio::third_party::thread_pool::submit ( const F &  task,
const A &...  args 
)
inline

Submit a function with zero or more arguments and no return value into the task queue, and get an std::future<bool> that will be set to true upon completion of the task.

Template Parameters
FThe type of the function.
AThe types of the zero or more arguments to pass to the function.
Parameters
taskThe function to submit.
argsThe zero or more arguments to pass to the function.
Returns
A future to be used later to check if the function has finished its execution.

Definition at line 260 of file thread_pool.hpp.

◆ submit() [2/2]

template<typename F , typename... A, typename R = std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>, typename = std::enable_if_t<!std::is_void_v<R>>>
std::future<R> kvikio::third_party::thread_pool::submit ( const F &  task,
const A &...  args 
)
inline

Submit a function with zero or more arguments and a return value into the task queue, and get a future for its eventual returned value.

Template Parameters
FThe type of the function.
AThe types of the zero or more arguments to pass to the function.
RThe return type of the function.
Parameters
taskThe function to submit.
argsThe zero or more arguments to pass to the function.
Returns
A future to be used later to obtain the function's returned value, waiting for it to finish its execution if needed.

Definition at line 294 of file thread_pool.hpp.


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