A lightweight, single-header C++ thread pool library with task prioritization
Single-header implementation. Just include and use—no builds or installations needed. Perfect for rapid development.
Efficient task management with priority queue. Execute high-priority tasks first while maintaining FIFO order for same-priority tasks.
Built with std::mutex and std::condition_variable for safe concurrent task execution without race conditions.
Built with C++11 standard. Works seamlessly on Linux, macOS, Windows, and other platforms supporting C++11.
Intuitive API with future/promise support. Get results from asynchronous tasks with minimal boilerplate code.
Singleton pattern with configurable thread count. Automatically scales to hardware concurrency or use custom thread count.
Getting started with LibThreadPool is incredibly simple. Since it's a header-only library, you just need to include the header file in your project.
Download the threadpool.h file from the repository or SourceForge.
Copy threadpool.h to your project directory and include it:
#include "threadpool.h"
Compile your project with C++11 support and pthread library:
g++ -std=c++11 your_program.cpp -pthread -o your_program
That's it! You're ready to use LibThreadPool in your project.
Here's a simple example to get you started:
#include <iostream>
#include "threadpool.h"
int main() {
// Initialize thread pool with 4 threads
InitializeThreadPool(4);
// Enqueue a simple task with priority 1
auto result = GetThreadPool()->enqueue(1, []() {
std::cout << "Hello from thread pool!" << std::endl;
return 42;
});
// Wait for result
std::cout << "Result: " << result.get() << std::endl;
return 0;
}
Tasks with lower priority values execute first:
#include <iostream>
#include <chrono>
#include <thread>
#include "threadpool.h"
void task(int id, int priority) {
std::cout << "Task " << id
<< " (priority " << priority << ") executing\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
int main() {
InitializeThreadPool(2);
// Enqueue tasks with different priorities
GetThreadPool()->enqueue(5, task, 1, 5); // Low priority
GetThreadPool()->enqueue(1, task, 2, 1); // High priority - executes first
GetThreadPool()->enqueue(3, task, 3, 3); // Medium priority
GetThreadPool()->enqueue(1, task, 4, 1); // High priority - executes second
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
Use std::future to retrieve results from tasks:
#include <iostream>
#include <vector>
#include "threadpool.h"
int calculate(int x) {
return x * x;
}
int main() {
InitializeThreadPool(4);
std::vector<std::future<int>> results;
// Enqueue multiple calculations
for (int i = 1; i <= 10; ++i) {
results.push_back(
GetThreadPool()->enqueue(1, calculate, i)
);
}
// Collect results
for (auto& result : results) {
std::cout << result.get() << " ";
}
std::cout << std::endl;
return 0;
}
#include <iostream>
#include "threadpool.h"
int main() {
InitializeThreadPool(4);
int multiplier = 5;
auto result = GetThreadPool()->enqueue(1, [multiplier](int x) {
return x * multiplier;
}, 10);
std::cout << "Result: " << result.get() << std::endl; // Output: 50
return 0;
}
| Function | Description |
|---|---|
InitializeThreadPool(n) |
Initialize the thread pool with n threads. If not called, defaults to std::thread::hardware_concurrency() |
GetThreadPool() |
Returns pointer to the singleton thread pool instance |
| Method | Description | Returns |
|---|---|---|
enqueue(priority, func, args...) |
Add a task to the thread pool with specified priority (lower = higher priority) | std::future<ReturnType> |
Each task contains:
All public methods are thread-safe and can be called from multiple threads simultaneously. The library uses:
std::mutex for protecting shared statestd::condition_variable for efficient thread wake-upstd::atomic for the running flag#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include "threadpool.h"
void processFile(const std::string& filename) {
std::ifstream file(filename);
// Process file contents...
std::cout << "Processed: " << filename << std::endl;
}
int main() {
InitializeThreadPool(8);
std::vector<std::string> files = {
"file1.txt", "file2.txt", "file3.txt", "file4.txt"
};
std::vector<std::future<void>> futures;
for (const auto& file : files) {
futures.push_back(
GetThreadPool()->enqueue(1, processFile, file)
);
}
// Wait for all files to be processed
for (auto& future : futures) {
future.get();
}
return 0;
}
#include <iostream>
#include <vector>
#include <random>
#include "threadpool.h"
void producer(int id) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
int data = dis(gen);
std::cout << "Producer " << id << " generated: " << data << std::endl;
}
void consumer(int id, int data) {
std::cout << "Consumer " << id << " processing: " << data << std::endl;
}
int main() {
InitializeThreadPool(4);
// High priority for producers
for (int i = 0; i < 5; ++i) {
GetThreadPool()->enqueue(1, producer, i);
}
// Lower priority for consumers
for (int i = 0; i < 5; ++i) {
GetThreadPool()->enqueue(2, consumer, i, i * 10);
}
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
#include <iostream>
#include <vector>
#include "threadpool.h"
struct Image {
std::string filename;
// Image data...
};
Image loadImage(const std::string& path) {
std::cout << "Loading: " << path << std::endl;
return Image{path};
}
Image applyFilter(const Image& img) {
std::cout << "Filtering: " << img.filename << std::endl;
return img;
}
void saveImage(const Image& img, const std::string& output) {
std::cout << "Saving to: " << output << std::endl;
}
int main() {
InitializeThreadPool(4);
std::vector<std::string> images = {
"img1.jpg", "img2.jpg", "img3.jpg"
};
for (const auto& imgPath : images) {
auto loadFuture = GetThreadPool()->enqueue(1, loadImage, imgPath);
auto filterFuture = GetThreadPool()->enqueue(2, applyFilter, loadFuture.get());
GetThreadPool()->enqueue(3, saveImage, filterFuture.get(), "output_" + imgPath);
}
std::this_thread::sleep_for(std::chrono::seconds(3));
return 0;
}
LibThreadPool is released under the MIT License. You are free to use, modify, and distribute this library in your projects, whether they are open source or commercial.
Found a bug or have a feature request? Feel free to open an issue or submit a pull request on the project repository. Contributions are always welcome!