Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SC::ThreadPool Struct Reference

Simple thread pool that executes tasks in a fixed number of worker threads. More...

#include <ThreadPool.h>

Public Types

using Task = ThreadPoolTask
 

Public Member Functions

Result create (size_t workerThreads)
 Create a thread pool with the requested number of worker threads.
 
Result destroy ()
 Destroy the thread pool created previously with ThreadPool::create.
 
Result queueTask (Task &task)
 Queue a task (that should not be already in use)
 
Result waitForAllTasks ()
 Blocks execution until all queued and pending tasks will be fully completed.
 
Result waitForTask (Task &task)
 Blocks execution until all queued and pending tasks will be fully completed.
 

Detailed Description

Simple thread pool that executes tasks in a fixed number of worker threads.

This class is not copyable / moveable due to it containing Mutex and Condition variable. Additionally, this class does not allocate any memory by itself, and expects the caller to supply SC::ThreadPool::Task objects.

Warning
The caller is responsible of keeping Task address stable until the it will be completed. If it's not already completed the task must still be valid during ThreadPool::destroy or ThreadPool destructor.

Example:

static const size_t wantedThreads = 4;
static const size_t numTasks = 100;
// 1. Create the threadpool with the wanted number of threads
SC::ThreadPool threadPool;
SC_TEST_EXPECT(threadPool.create(wantedThreads));
size_t values[numTasks];
// 2. Allocate the wanted number of tasks. Tasks memory should be valid until a task is finished.
SC::ThreadPool::Task tasks[numTasks];
for (size_t idx = 0; idx < numTasks; idx++)
{
size_t* value = values + idx;
*value = idx;
// 3. Setup the task function to execute on some random thread
tasks[idx].function = [value]()
{
if (*value % 2)
{
}
*value *= 100;
};
// 4. Queue the task in thread pool
SC_TEST_EXPECT(threadPool.queueTask(tasks[idx]));
}
// 5. [Optional] Wait for a single task
SC_TEST_EXPECT(threadPool.waitForTask(tasks[1]));
SC_TEST_EXPECT(values[1] == 100);
// 6. [Optional] Wait for all remaining tasks to be finished
// Checking Results
bool allGood = true;
for (size_t idx = 0; idx < numTasks; idx++)
{
allGood = allGood && (values[idx] == idx * 100);
}
SC_TEST_EXPECT(allGood);
// 6. [Optional] Destroy the threadpool.
// Note: destructor will wait for tasks to finish, but this avoids it from accessing invalid tasks,
// as stack objects are reclaimed in inverse declaration order
SC_TEST_EXPECT(threadPool.destroy());

Member Function Documentation

◆ create()

Result SC::ThreadPool::create ( size_t workerThreads)
nodiscard

Create a thread pool with the requested number of worker threads.

◆ destroy()

Result SC::ThreadPool::destroy ( )
nodiscard

Destroy the thread pool created previously with ThreadPool::create.

Warning
Tasks that are queued will NOT be executed (but you can use ThreadPool::waitForAllTasks for that)

◆ queueTask()

Result SC::ThreadPool::queueTask ( Task & task)
nodiscard

Queue a task (that should not be already in use)

◆ waitForAllTasks()

Result SC::ThreadPool::waitForAllTasks ( )
nodiscard

Blocks execution until all queued and pending tasks will be fully completed.

◆ waitForTask()

Result SC::ThreadPool::waitForTask ( Task & task)
nodiscard

Blocks execution until all queued and pending tasks will be fully completed.


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