VeloGraphX
High-performance dynamic graph analytics in C++20
Loading...
Searching...
No Matches
thread_pool.hpp
Go to the documentation of this file.
1#pragma once
2#include <atomic>
3#include <condition_variable>
4#include <cstddef>
5#include <functional>
6#include <mutex>
7#include <queue>
8#include <thread>
9#include <vector>
10
11namespace velographx {
13 public:
14 explicit ThreadPool(std::size_t threads = std::thread::hardware_concurrency()) : stop_(false) {
15 if (threads == 0) threads = 1;
16 workers_.reserve(threads);
17 for (std::size_t i=0;i<threads;++i) workers_.emplace_back([this]{ worker(); });
18 }
20 { std::lock_guard<std::mutex> lock(mu_); stop_ = true; }
21 cv_.notify_all();
22 for (auto& t : workers_) if (t.joinable()) t.join();
23 }
24 void submit(std::function<void()> fn) {
25 { std::lock_guard<std::mutex> lock(mu_); tasks_.push(std::move(fn)); }
26 cv_.notify_one();
27 }
28 void wait_idle() {
29 std::unique_lock<std::mutex> lock(mu_);
30 idle_cv_.wait(lock,[this]{ return tasks_.empty() && active_==0; });
31 }
32 private:
33 void worker() {
34 for (;;) {
35 std::function<void()> fn;
36 { std::unique_lock<std::mutex> lock(mu_); cv_.wait(lock,[this]{return stop_||!tasks_.empty();}); if(stop_&&tasks_.empty()) return; fn=std::move(tasks_.front()); tasks_.pop(); ++active_; }
37 fn();
38 { std::lock_guard<std::mutex> lock(mu_); --active_; if(tasks_.empty()&&active_==0) idle_cv_.notify_all(); }
39 }
40 }
41 std::vector<std::thread> workers_; std::queue<std::function<void()>> tasks_; std::mutex mu_; std::condition_variable cv_, idle_cv_; bool stop_; std::size_t active_{0};
42};
43} // namespace velographx
ThreadPool(std::size_t threads=std::thread::hardware_concurrency())
void submit(std::function< void()> fn)