#include <ThreadPool.h>
Classes | |
struct | QMax |
struct | Statistics |
Public Types | |
using | TaskType = Function< void()> |
Public Member Functions | |
ThreadPool () | |
~ThreadPool () | |
nonvirtual Options | GetOptions () const |
nonvirtual unsigned int | GetPoolSize () const |
nonvirtual void | SetPoolSize (unsigned int poolSize) |
nonvirtual TaskType | AddTask (const TaskType &task, const optional< Characters::String > &name=nullopt) |
nonvirtual void | AbortTask (const TaskType &task, Time::DurationSeconds timeout=Time::kInfinity) |
nonvirtual void | AbortTasks (Time::DurationSeconds timeout=Time::kInfinity) |
nonvirtual bool | IsPresent (const TaskType &task) const |
nonvirtual bool | IsRunning (const TaskType &task) const |
nonvirtual void | WaitForTask (const TaskType &task, Time::DurationSeconds timeout=Time::kInfinity) const |
nonvirtual Containers::Collection< TaskInfo > | GetTasks () const |
returns GetPendingTasks () + GetRunningTasks () - but also some extra information about each task | |
nonvirtual Containers::Collection< TaskType > | GetPendingTasks () const |
nonvirtual Containers::Collection< TaskType > | GetRunningTasks () const |
nonvirtual size_t | GetTasksCount () const |
return total number of tasks, either pending, or currently running. | |
nonvirtual size_t | GetPendingTasksCount () const |
return GetPendingTasks ().size (), except probably much more efficient | |
nonvirtual void | WaitForTasksDone (const Traversal::Iterable< TaskType > &tasks, Time::DurationSeconds timeout=Time::kInfinity) const |
nonvirtual void | WaitForTasksDoneUntil (const Traversal::Iterable< TaskType > &tasks, Time::TimePointSeconds timeoutAt) const |
nonvirtual void | ResetStatistics () |
nonvirtual Statistics | GetCurrentStatistics () const |
nonvirtual Characters::String | ToString () const |
The ThreadPool class creates a small fixed number of Thread objects, and lets you use them as if there were many more. You submit a task (representable as a comparable std::function -
If as Task in the thread pool raises an exception - this will be IGNORED (except for the special case of Thread::AbortException which is used internally to end the threadpool or remove some threads). Because of this, your submitted runnables should take care of their own error handling internally.
ThreadPool mainly useful for servicing lost-cost calls/threads, where the overhead of constructing the thread is significant compared to the cost of performing the action, and where the priority & stacksize can all be predetermined and 'shared'. Also - where you want to CONTROL the level of thread creation (possibly to avoid DOS attacks or just accidental overloading).
Definition at line 72 of file ThreadPool.h.
using Stroika::Foundation::Execution::ThreadPool::TaskType = Function<void ()> |
This means periodically calling CheckForInterruption () and that any waits respect thread cancelation (stop_token).
Tasks may exit via exception, but nothing will be done with that exception (beyond DbgTrace logging). So generally not a good idea, except for ThreadAbort handling.
Definition at line 156 of file ThreadPool.h.
Stroika::Foundation::Execution::ThreadPool::ThreadPool | ( | ) |
Definition at line 13 of file ThreadPool.inl.
ThreadPool::~ThreadPool | ( | ) |
Destroying a threadpool implicitly calls AbortAndWaitForDone () and eats any errors (cannot rethrow).
Definition at line 139 of file ThreadPool.cpp.
auto Stroika::Foundation::Execution::ThreadPool::GetOptions | ( | ) | const |
These options have have been modified by various APIs, and reflect the current state of options, not necessarily those that the ThreadPool was created with.
Definition at line 17 of file ThreadPool.inl.
unsigned int ThreadPool::GetPoolSize | ( | ) | const |
This returns the number of threads in the pool (not the number of tasks). Note 0 is a legal size.
Definition at line 145 of file ThreadPool.cpp.
void ThreadPool::SetPoolSize | ( | unsigned int | poolSize | ) |
SetPoolSize () is advisory. It attempts to add or remove entries as requested. Note - 0 is a legal size.
But under some circumstances, it will fail. For example, if tasks are busy running on all threads, the number of threads in the pool cannot be decreased.
Definition at line 151 of file ThreadPool.cpp.
ThreadPool::TaskType Stroika::Foundation::Execution::ThreadPool::AddTask | ( | const TaskType & | task, |
const optional< Characters::String > & | name = nullopt |
||
) |
Push the given task into the queue (possibly blocking til space in the Q or throwing if no space in Q, but does NOT block waiting for Q to till).
if qmax is provided, it takes precedence over any default value associated with the ThreadPool (constructor). If neither provided (as an argument or associated with the pool, this is treated as no max, and the addition just proceeds.
If qMax provided (even indirectly), assure task q length doesn't exceed argument by waiting up to the qMax duration, and either timing out, or successfully add the task.
Definition at line 24 of file ThreadPool.inl.
void ThreadPool::AbortTask | ( | const TaskType & | task, |
Time::DurationSeconds | timeout = Time::kInfinity |
||
) |
It is NOT an error to call this with a task that is not in the Queue (since it would be a race to try to find out if it was already executed.
It can cancel a task if it has not yet been started, or EVEN if its already in progress (see Thread::Abort - it sends abort signal)
The function doesn't return until the task has been successfully cancelled, or it throws if timeout.
Definition at line 229 of file ThreadPool.cpp.
void ThreadPool::AbortTasks | ( | Time::DurationSeconds | timeout = Time::kInfinity | ) |
See AbortTask () - it aborts all tasks - if any.
Definition at line 271 of file ThreadPool.cpp.
bool ThreadPool::IsPresent | ( | const TaskType & | task | ) | const |
returns true if queued OR actively running.
Definition at line 295 of file ThreadPool.cpp.
bool ThreadPool::IsRunning | ( | const TaskType & | task | ) | const |
returns true actively running
Definition at line 317 of file ThreadPool.cpp.
void ThreadPool::WaitForTask | ( | const TaskType & | task, |
Time::DurationSeconds | timeout = Time::kInfinity |
||
) | const |
throws if timeout. Returns when task has completed (or if not in task q)
Definition at line 329 of file ThreadPool.cpp.
auto ThreadPool::GetPendingTasks | ( | ) | const |
return all tasks which are queued, but haven't yet been assigned to a thread.
Definition at line 392 of file ThreadPool.cpp.
auto ThreadPool::GetRunningTasks | ( | ) | const |
return all tasks which are currently running (assigned to some thread in the thread pool).
Definition at line 365 of file ThreadPool.cpp.
size_t ThreadPool::GetTasksCount | ( | ) | const |
return total number of tasks, either pending, or currently running.
This is GetRunningTasks().size () + GetPendingTasks ().size (), or alternatively GetTasks.size (), but more efficient.
Definition at line 378 of file ThreadPool.cpp.
void Stroika::Foundation::Execution::ThreadPool::WaitForTasksDone | ( | const Traversal::Iterable< TaskType > & | tasks, |
Time::DurationSeconds | timeout = Time::kInfinity |
||
) | const |
Wait for the given amount of time for all (either given argument or all tasks in this thread pool) to be done.
When called with a specific set of tasks, this procedure waits for exactly those tasks. When called with no task argument, it waits until GetTaskCount () == 0.
Definition at line 33 of file ThreadPool.inl.
void ThreadPool::WaitForTasksDoneUntil | ( | const Traversal::Iterable< TaskType > & | tasks, |
Time::TimePointSeconds | timeoutAt | ||
) | const |
Wait for the given amount of time for all (either given argument or all tasks in this thread pool) to be done.
When called with a specific set of tasks, this procedure waits for exactly those tasks. When called with no task argument, it waits until GetTaskCount () == 0.
Definition at line 408 of file ThreadPool.cpp.
void ThreadPool::ResetStatistics | ( | ) |
Definition at line 436 of file ThreadPool.cpp.
auto ThreadPool::GetCurrentStatistics | ( | ) | const |
Definition at line 443 of file ThreadPool.cpp.
String ThreadPool::ToString | ( | ) | const |
a helpful debug dump of the ThreadPool status
Definition at line 495 of file ThreadPool.cpp.