An open API service indexing awesome lists of open source software.

https://github.com/abin-z/threadpool

A cross-platform, header-only C++11 thread pool (线程池)
https://github.com/abin-z/threadpool

cpp cpp11 mutilthread task task-manager threadpool

Last synced: about 1 month ago
JSON representation

A cross-platform, header-only C++11 thread pool (线程池)

Awesome Lists containing this project

README

          

# Lightweight Thread Pool (C++11)

[![threadpool](https://img.shields.io/badge/Thread_Pool-8A2BE2)](https://github.com/abin-z/ThreadPool) [![headeronly](https://img.shields.io/badge/Header_Only-green)](include/thread_pool/thread_pool.h) [![moderncpp](https://img.shields.io/badge/Modern_C%2B%2B-218c73)](https://learn.microsoft.com/en-us/cpp/cpp/welcome-back-to-cpp-modern-cpp?view=msvc-170) [![licenseMIT](https://img.shields.io/badge/License-MIT-green)](https://opensource.org/license/MIT) [![version](https://img.shields.io/badge/version-0.9.2-green)](https://github.com/abin-z/ThreadPool/releases)

🌍 Languages/语言: [English](README.md) | [简体中文](README.zh-CN.md)

**A cross-platform, header-only, task-based C++11 thread pool supporting arbitrary arguments and return values via `std::future`.**

## 📌 Overview

A **Thread Pool** is a tool that manages threads based on the **pooling concept**, commonly used in multithreaded programming.

The core idea is: **a certain number of threads are pre-created and placed in a "pool". When a task arrives, it is assigned to an idle thread for processing, rather than creating a new thread every time.**

![Thread_pool.svg](assets/Thread_pool.svg.png)

## ✨ Features

- **Flexible Task Submission**: Supports arbitrary callable types with arguments; returns a `std::future`
- **Thread-Safe**: Built using `std::mutex`, `std::condition_variable`, and `std::atomic`
- **Cross-Platform**: Pure C++11 implementation, works on Windows, Linux, and more
- **Header-Only**: Just include the single file `thread_pool.h` in your project
- **RAII Resource Management**: Threads are cleanly shut down in destructor
- **Task Completion Wait**: Supports waiting for all tasks to finish with `wait_all()`
- **Shutdown Modes**:
- `WaitForAllTasks`: Complete all tasks before shutdown
- `DiscardPendingTasks`: Discard pending tasks and shut down immediately

## 📦 Getting Started

### Installation

Copy [`thread_pool.h`](thread_pool/include/thread_pool/thread_pool.h) into your project and include it:

```cpp
#include "thread_pool.h"
```

No additional dependencies required.

### Basic Example

**basic usage**

```cpp
#include "thread_pool.h"
#include

int main() {
abin::threadpool pool(4);

auto future1 = pool.submit([] { return 42; });
std::cout << "Result: " << future1.get() << "\n";

auto future2 = pool.submit([](int a, int b) { return a + b; }, 5, 7);
std::cout << "Sum: " << future2.get() << "\n";

return 0;
}
```

**Submit a callable object of any type with any arguments**

Click to expand and view the code

```cpp
#include "thread_pool.h"

#include
#include
#include
#include

void normal_function(int x)
{
std::cout << "normal_function: " << x << std::endl;
}

struct MyClass
{
void member_function(int y)
{
std::cout << "MyClass::member_function: " << y << std::endl;
}
int add(int a, int b)
{
return a + b;
}
};

struct Functor
{
void operator()(const std::string& msg) const
{
std::cout << "Functor called with: " << msg << std::endl;
}
};

int main()
{
abin::threadpool pool(4);

// Submit a regular function
pool.submit(normal_function, 42);

// Submit a lambda without capture
pool.submit([] { std::cout << "lambda no capture\n"; });

// Submit a lambda with capture
int value = 99;
pool.submit([value] { std::cout << "lambda with capture: " << value << "\n"; });

// Submit a member function using lambda
MyClass obj;
pool.submit([&obj] { obj.member_function(123); });

// Submit a member function using std::mem_fn
std::future ret = pool.submit(std::mem_fn(&MyClass::add), &obj, 3, 4);
std::cout << "add result1: " << ret.get() << "\n";

// Submit a member function using std::bind
std::future fut_add = pool.submit(std::bind(&MyClass::add, &obj, 2, 3));
std::cout << "add result2: " << fut_add.get() << "\n";

// Submit a function object (functor)
Functor f;
pool.submit(f, "hello functor");

// Submit using std::bind
auto bound = std::bind(&MyClass::add, &obj, 5, 6);
std::future fut_bound = pool.submit(bound);
std::cout << "bound result: " << fut_bound.get() << "\n";

// Submit a std::packaged_task (Note: older versions of MSVC may report errors)
std::packaged_task task([] { return std::string("from packaged_task"); });
std::future fut_str = task.get_future();
pool.submit(std::move(task)); // Must be moved
std::cout << "packaged_task result: " << fut_str.get() << "\n";

pool.wait_all(); // Wait for all tasks to finish
std::cout << "===All tasks completed.===\n";
}
```

For more detailed use cases, please go to the [`examples`](examples/) folder to view them.

## 📄 API Reference

### Constructor & Destructor

```cpp
explicit threadpool(std::size_t thread_count = default_thread_count());
~threadpool();
```

- Initializes and launches the thread pool
- Thread count defaults to `std::thread::hardware_concurrency()`, or 4 if unknown
- Destructor automatically shuts down all threads (waits for tasks to complete)

------

### Task Submission

```cpp
template
auto submit(F&& f, Args&&... args) -> std::future;
```

- Asynchronously submits a task
- Returns a `std::future` for the result
- Throws `std::runtime_error` if the pool is stopped

------

### Waiting for Completion

```cpp
void wait_all();
```

- Blocks until all tasks have finished
- Returns immediately if no tasks are pending

------

### Shutdown

```cpp
void shutdown(shutdown_mode mode = shutdown_mode::WaitForAllTasks);
```

- Gracefully or forcefully stops the thread pool
- Cannot submit new tasks after shutdown

------

### Restart

```cpp
void reboot(std::size_t thread_count);
```

- Shuts down current pool and restarts with new thread count
- No effect if the pool is already running

------

### Status Queries

```cpp
bool is_running() const noexcept; // Whether the thread pool is running
std::size_t total_threads() const noexcept; // Total number of threads
std::size_t busy_threads() const noexcept; // Number of busy threads
std::size_t idle_threads() const noexcept; // Number of idle threads
std::size_t pending_tasks() const noexcept; // Number of pending tasks
threadpool::status_info status() const noexcept; // Summary of status info
```

- Provides detailed insight into the internal state of the pool

------

## ✅ Recommended Scenarios for Using a Thread Pool

| Scenario | Reason |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| Need to execute **a large number of small, independent tasks** | Avoid frequent thread creation/destruction, improve efficiency |
| Tasks are short-lived | Encourages thread reuse and fast response |
| Tasks are **non-blocking** | Prevents thread pool threads from being tied up |
| Want to control concurrency and save resources | Limit thread count to avoid system overload |
| Background asynchronous task handling | E.g., logging, delayed execution, event callbacks |
| Need unified thread lifecycle management | Easier centralized control, restarting, and destruction |
| Using `future`/`promise`-based mechanisms to retrieve results | Thread pool naturally fits task submission with result retrieval |

## ⚠️ Scenarios Where a Thread Pool Is Not Recommended

| Scenario | Reason |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| Need a **foreground thread** | Thread pool threads are background by default, process can't rely on them to stay alive |
| Need to **set thread priority** | Thread pool threads typically don't allow custom priority |
| **Tasks block for a long time** (e.g., I/O, locks) | May exhaust the pool, blocking other tasks from starting |
| Need to place thread in a **single-threaded apartment (STA)** | Thread pool threads are usually in multi-threaded apartment (MTA) |
| Need threads with **stable identity or persistent state** | Thread pool threads are reused, not bound to specific context |
| Need a thread **dedicated to a long-running task** | Custom thread is more suitable for holding context and stability |

## 💡 Contribution Guidelines

🗨️ Welcome to submit **Issue** and **Pull request** to improve this project!

-----

## 🙌 Acknowledgements

Thanks to **[Catch2](https://github.com/catchorg/Catch2)** for providing great support and helping with unit testing of this project!

Thanks to **https://github.com/progschj/ThreadPool** for providing inspiration for this project!

------

## 📜 License

This project uses the [ **MIT** License](./LICENSE).

Copyright © 2025–Present Abin.

------

## 🙋‍♂️ Author

**Abin** 📎 [GitHub](https://github.com/abin-z)