From b95431499f5fc5a34337cd7acd771dfeaf2eff43 Mon Sep 17 00:00:00 2001 From: ruinivist Date: Tue, 13 Jan 2026 03:01:18 +0000 Subject: [PATCH] older thread pool impl with perfect forwarding, to recall later --- thread-pool/pool.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 thread-pool/pool.cpp diff --git a/thread-pool/pool.cpp b/thread-pool/pool.cpp new file mode 100644 index 0000000..aabcc95 --- /dev/null +++ b/thread-pool/pool.cpp @@ -0,0 +1,84 @@ +#include +using namespace std; + +class ThreadPool { + private: + vector workers; + queue> tasks; + mutex mtx; + condition_variable cv; + bool stop = false; + + public: + ThreadPool(int num_threads) { + while (num_threads-- > 0) { + workers.emplace_back([this] { + while (true) { + function task; + { + unique_lock lock(mtx); + cv.wait(lock, + [this] { return stop || !tasks.empty(); }); + + if (stop && tasks.empty()) return; + + task = std::move(tasks.front()); + tasks.pop(); + } + task(); + } + }); + } + } + + template + future::type> enqueue(F&& f, + Args&&... args) { + if (stop) throw std::runtime_error("enqueue on stopped ThreadPool"); + + using return_type = typename std::result_of::type; + // this is not calling the return type its a func with no args and + // returning return type value as in int(int) this is int() + auto task = make_shared>( + bind(forward(f), forward(args)...)); + future fut = task->get_future(); + // since its a share pointer so the task lives as long as future lives + // you could not make it shared but then pool might die with future + // being invalid now the desctructor isn't called now unless the future + // also goes out of scope + + { + unique_lock lock(mtx); + tasks.emplace([task] { (*task)(); }); + } + + cv.notify_one(); + return fut; + } + + ~ThreadPool() { + { + unique_lock lock(mtx); + stop = true; + } + + cv.notify_all(); + for (auto& worker : workers) worker.join(); + } +}; + +int main() { + ThreadPool pool(4); + + auto taskFunction = [](int a, int& b, std::string&& c) { + std::cout << "Task executed with: " << a << ", " << b << ", " << c + << std::endl; + b *= 2; // Modify the lvalue reference + return a + b; + }; + + int lval = 10; + auto future = pool.enqueue(taskFunction, 5, ref(lval), "hello"); + + cout << "result: " << future.get() << endl; +} \ No newline at end of file