A modern thread pool implementation based on C++20

Overview

thread-pool

say thanks Discord

Ubuntu Windows Style Install

A simple, functional thread pool implementation using pure C++20.

Features

  • Built entirely with C++20
  • Enqueue tasks with or without tracking results

Integration

dp::thread-pool is a header only library. All the files needed are in include/thread_pool.

CMake

ThreadPool defines two CMake targets:

  • ThreadPool::ThreadPool
  • dp::thread-pool

You can then use find_package():

find_package(dp::thread-pool REQUIRED)

Alternatively, you can use something like CPM which is based on CMake's Fetch_Content module.

CPMAddPackage(
    NAME thread-pool
    GITHUB_REPOSITORY DeveloperPaul123/thread-pool
    GIT_TAG #0cea9c12fb30cb677696c0dce6228594ce26171a change this to latest commit or release tag
)

Usage

Simple example:

// create a thread pool with a specified number of threads.
dp::thread_pool pool(4);

// add tasks, in this case without caring about results of individual tasks
pool.enqueue_detach([](int value) { /*...your task...*/ }, 34);
pool.enqueue_detach([](int value) { /*...your task...*/ }, 37);
pool.enqueue_detach([](int value) { /*...your task...*/ }, 38);
// and so on..

You can see other examples in the /examples folder.

Benchmarks

See the ./benchmark folder for the benchmark code. The benchmarks are set up to compare matrix multiplication using the dp::thread_pool versus std::async. A summary of the comparisons is below. Benchmarks were run using the windows-release CMake preset (see CMakePresets.json).

Machine Specs

  • AMD Ryzen 7 1800X (16 X 3593 MHz CPUs)
  • CPU Caches:
    • L1 Data 32 KiB (x8)
    • L1 Instruction 64 KiB (x8)
    • L2 Unified 512 KiB (x8)
    • L3 Unified 8192 KiB (x2)
  • 32 GB RAM

Summary of Results

Matrix sizes are all square (MxM). Each multiplication is (MxM) * (MxM) where * refers to a matrix multiplication operation.

Matrix Size Number of multiplications std::async time (ms) dp::thread_pool time (ms)
8 25,000 77.9 198
64 5,000 100 84.9
256 250 295 59.0
512 75 713 69.3
1024 10 1160 73.8

Building

This project has been built with:

  • Visual Studio 2022
  • Clang 10.+ (via WSL on Windows)
  • GCC 11.+ (vis WSL on Windows)
  • CMake 3.21+

To build, run:

cmake -S . -B build
cmake --build build

Build Options

Option Description Default
TP_BUILD_TESTS Turn on to build unit tests. Required for formatting build targets. ON
TP_BUILD_EXAMPLES Turn on to build examples ON

Run clang-format

Use the following commands from the project's root directory to check and fix C++ and CMake source style. This requires clang-format, cmake-format and pyyaml to be installed on the current system. To use this feature you must turn on TP_BUILD_TESTS.

# view changes
cmake --build build/test --target format

# apply changes
cmake --build build/test --target fix-format

See Format.cmake for details.

Build the documentation

The documentation is automatically built and published whenever a GitHub Release is created. To manually build documentation, call the following command.

cmake -S documentation -B build/doc
cmake --build build/doc --target GenerateDocs
# view the docs
open build/doc/doxygen/html/index.html

To build the documentation locally, you will need Doxygen and Graphviz on your system.

Contributing

Contributions are very welcome. Please see contribution guidelines for more info.

License

The project is licensed under the MIT license. See LICENSE for more details.

Author


@DeveloperPaul123
Comments
  • How could we declare a variable or pointer of  dp::thread_pool

    How could we declare a variable or pointer of dp::thread_pool

    How could we declare variable dp::thread_pool, for example, //in a header h dp::thread_pool pool_var; //Or dp::thread_pool * pool_ptr; in a cpp pool_var = dp::thread_pool();

       dp::thread_pool pool
       pool_ptr = &pool;
    
    opened by chenscottus 4
  • Distribute Task Workload Across Threads Based on Thread Performance

    Distribute Task Workload Across Threads Based on Thread Performance

    Summary

    Switched to using a single task queue for all threads and a std::condition_variable_any to wake the threads when there is work available. This serves to better balance work loads and ensures the total work completes as quickly as possible.

    Fixed

    • #4
    • Minor issues in documentation

    Changed

    • Removed front() and back() member functions from dp::thread_safe_queue.
    • Use a single task queue for all threads
    opened by DeveloperPaul123 0
  • [FEATURE] Improve Task Load Distribution Among Threads

    [FEATURE] Improve Task Load Distribution Among Threads

    In the case that tasks don't all take the same amount of time, this could skew the work loads to be "harder" on certain threads, instead of spreading the work uniformly across threads.

    One possible solution for this is to use a single work queue for all threads instead of having one per thread. See this for more info.

    enhancement help wanted 
    opened by DeveloperPaul123 0
  • Improvements and Simplifications to ThreadPool

    Improvements and Simplifications to ThreadPool

    Improvements/changes largely based on feedback from Code Review and Reddit

    Changed

    • Simplified class definition and removed unused typedefs (YAGNI)
    • Also removed Queue template parameter (also YAGNI)
    • Use std::deque instead of std::queue in dp::thread_safe_queue
    • Use std::deque in dp::thread_pool so that usage of std::unique_ptr is no longer needed for internal task objects.

    Fixed

    • Issues with dp::thread_safe_queue's usage of lock guards before notifying threads of new data being available.
    • Ensure that all tasks complete before the thread pool is destroyed.
    opened by DeveloperPaul123 0
  • Fix Unit Tests

    Fix Unit Tests

    Fixed

    • Issues with running unit tests with ctest.

    Added

    • Basic unit test for queue type.

    Changed

    • Changed queue class name from safe_queue to thread_safe_queue.
    opened by DeveloperPaul123 0
  • use feature test macro to check feature available

    use feature test macro to check feature available

    Reason

    thread-pool is a great modern and tiny thread pool. However, using the compiler version to check move_only_function is not solid. For example:

    I used g++-12 (Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0. The library could not compile due to:

    error: ‘move_only_function’ in namespace ‘std’ does not name a template type 25 | using default_function_type = std::move_only_function<void()>; | ^~~~~~~~~~~~~~~~~~

    Here is the ci for detailed information.

    Hence, I tried to use feature testing instead and it works well.

    I am sure that I may have missed something. :)

    opened by cauliyang 2
  • Adding support for using this thread pool with coroutines

    Adding support for using this thread pool with coroutines

    Note This is on hold until I can ensure that the necessary build flags are properly set in the dp::thread-pool for coroutine support. It seems that down-stream projects for coroutines don't set these in the targets properly but I want dp::thread-pool to do this.

    Changes

    • Updated CPM.cmake version
    • Added schedule() function to allow for running coroutines on the thread pool
    • Added batch enqueue() function to better compare to coroutine performance
    opened by DeveloperPaul123 0
Releases(0.5.0)
  • 0.5.0(May 14, 2022)

    What's Changed

    • Add Basic Benchmarks by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/9
    • Add CMakePresets.json by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/10
    • Use Multi-Queue with Work Stealing by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/11
    • Ensure tasks get executed in thread-pool destructor by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/12

    Full Changelog: https://github.com/DeveloperPaul123/thread-pool/compare/0.4.1...0.5.0

    Source code(tar.gz)
    Source code(zip)
  • 0.4.1(Feb 24, 2022)

  • 0.4.0(Feb 24, 2022)

    What's Changed

    • Distribute Task Workload Across Threads Based on Thread Performance by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/7

    Full Changelog: https://github.com/DeveloperPaul123/thread-pool/compare/0.3.0...0.4.0

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Dec 29, 2021)

    What's Changed

    • Improvements and Simplifications to ThreadPool by @DeveloperPaul123 in https://github.com/DeveloperPaul123/thread-pool/pull/3

    Full Changelog: https://github.com/DeveloperPaul123/thread-pool/compare/0.2.0...0.3.0

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Nov 19, 2021)

    Changed

    • Changed the way parameter pack expansion is handled in a lambda init. Altered so that we can now take advantage of C++20 features and remove usage of std::make_tuple and std::apply.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Nov 19, 2021)

Thread-pool-cpp - High performance C++11 thread pool

thread-pool-cpp It is highly scalable and fast. It is header only. No external dependencies, only standard library needed. It implements both work-ste

Andrey Kubarkov 535 Sep 9, 2022
A modern thread pool implementation based on C++20

thread-pool A simple, functional thread pool implementation using pure C++20. Features Built entirely with C++20 Enqueue tasks with or without trackin

Paul T 128 Oct 2, 2022
CTPL - Modern and efficient C++ Thread Pool Library

CTPL Modern and efficient C++ Thread Pool Library A thread pool is a programming pattern for parallel execution of jobs, http://en.wikipedia.org/wiki/

null 1.1k Sep 30, 2022
An ultra-simple thread pool implementation for running void() functions in multiple worker threads

void_thread_pool.cpp © 2021 Dr Sebastien Sikora. [email protected] Updated 06/11/2021. What is it? void_thread_pool.cpp is an ultra-simple

Seb Sikora 1 Nov 19, 2021
ThreadPool - A simple C++11 Thread Pool implementation

ThreadPool A simple C++11 Thread Pool implementation. Basic usage: // create thread pool with 4 worker threads ThreadPool pool(4); // enqueue and sto

Jakob Progsch 5.9k Oct 1, 2022
Pool is C++17 memory pool template with different implementations(algorithms)

Object Pool Description Pool is C++17 object(memory) pool template with different implementations(algorithms) The classic object pool pattern is a sof

KoynovStas 1 Sep 27, 2022
High Performance Linux C++ Network Programming Framework based on IO Multiplexing and Thread Pool

Kingpin is a C++ network programming framework based on TCP/IP + epoll + pthread, aims to implement a library for the high concurrent servers and clie

null 21 Sep 30, 2022
A easy to use multithreading thread pool library for C. It is a handy stream like job scheduler with an automatic garbage collector. This is a multithreaded job scheduler for non I/O bound computation.

A easy to use multithreading thread pool library for C. It is a handy stream-like job scheduler with an automatic garbage collector for non I/O bound computation.

Hyoung Min Suh 12 Jun 4, 2022
A C++17 thread pool for high-performance scientific computing.

We present a modern C++17-compatible thread pool implementation, built from scratch with high-performance scientific computing in mind. The thread pool is implemented as a single lightweight and self-contained class, and does not have any dependencies other than the C++17 standard library, thus allowing a great degree of portability

Barak Shoshany 929 Oct 3, 2022
An easy to use C++ Thread Pool

mvThreadPool (This library is available under a free and permissive license) mvThreadPool is a simple to use header only C++ threadpool based on work

Jonathan Hoffstadt 31 Sep 24, 2022
EOSP ThreadPool is a header-only templated thread pool writtent in c++17.

EOSP Threadpool Description EOSP ThreadPool is a header-only templated thread pool writtent in c++17. It is designed to be easy to use while being abl

null 1 Apr 22, 2022
Work Stealing Thread Pool

wstpool Work Stealing Thread Pool, Header Only, C++ Threads Consistent with the C++ async/future programming model. Drop-in replacement for 'async' fo

Yasser Asmi 4 Aug 13, 2022
MAN - Man is Thread Pool in C++17

Introduction MAN is a ThreadPool wrote in C++17. The name is chosen because, at least in France, it is said that men are not able to do several things

Antoine MORRIER 6 Mar 6, 2022
ThreadPool - A fastest, exception-safety and pure C++17 thread pool.

Warnings Since commit 468129863ec65c0b4ede02e8581bea682351a6d2, I move ThreadPool to C++17. (To use std::apply.) In addition, the rule of passing para

Han-Kuan Chen 121 Sep 9, 2022
Objectpool - Object pool implementation in C++11

Object pool allocator This is a C++11 implementation of an object pool allocator. For more information on object pool allocators and their purpose see

Cameron Hart 65 Sep 15, 2022
BabyCoin: mining pool

BabyCoin Pool Based on cryptonote-nodejs-pool cryptonote-nodejs-pool High performance Node.js (with native C addons) mining pool for CryptoNote based

null 1 May 15, 2022
A hybrid thread / fiber task scheduler written in C++ 11

Marl Marl is a hybrid thread / fiber task scheduler written in C++ 11. About Marl is a C++ 11 library that provides a fluent interface for running tas

Google 1.4k Sep 28, 2022
Simple and fast C library implementing a thread-safe API to manage hash-tables, linked lists, lock-free ring buffers and queues

libhl C library implementing a set of APIs to efficiently manage some basic data structures such as : hashtables, linked lists, queues, trees, ringbuf

Andrea Guzzo 390 Sep 6, 2022
Fork of rpmalloc to be used with single thread applications and old C compilers

srpmalloc - Small rpmalloc This is a fork of rpmalloc, with the intent to be used in single threaded applications only, with old C99 compilers, and in

Eduardo Bart 6 Apr 30, 2022