3#include <condition_variable>
21 std::condition_variable_any
cv;
22 std::function<void()>
func;
25 void run(std::stop_token stop);
31 explicit thread_pool(
size_t num_threads = std::thread::hardware_concurrency())
35 threads.emplace_back([&state](std::stop_token stop) { state.run(std::move(stop)); });
43 void schedule(
size_t i, std::function<
void()> func) {
45 std::unique_lock lck{state.mtx};
46 state.func = std::move(func);
48 state.cv.notify_all();
53 std::unique_lock lck{state.mtx};
54 state.cv.wait(lck, [&] {
return !state.func; });
55 if (
auto &e = state.exception)
56 std::rethrow_exception(std::exchange(e,
nullptr));
60 for (
size_t i = 0; i <
size(); ++i)
64 template <
class I =
size_t,
class F>
66 const auto n =
size();
67 for (
size_t i = 0; i < n; ++i)
68 schedule(i, [&f, i, n] { f(
static_cast<I
>(i),
static_cast<I
>(n)); });
72 template <
class I =
size_t,
class F>
74 if (
static_cast<size_t>(n) >
size())
75 throw std::invalid_argument(
"Not enough threads in pool");
76 for (
size_t i = 0; i < static_cast<size_t>(n); ++i)
77 schedule(i, [&f, i, n] { f(
static_cast<I
>(i), n); });
78 for (
size_t i = 0; i < static_cast<size_t>(n); ++i)
87 std::unique_lock lck{
mtx};
88 cv.wait(lck, stop, [&] {
return static_cast<bool>(
func); });
89 if (stop.stop_requested()) {
106extern std::optional<thread_pool>
pool;
117template <
class I =
size_t,
class F>
129template <
class I =
size_t,
class F>
void sync_run_n(I n, F &&f)
thread_pool & operator=(const thread_pool &)=delete
thread_pool(size_t num_threads=std::thread::hardware_concurrency())
std::vector< State > states
void schedule(size_t i, std::function< void()> func)
thread_pool(const thread_pool &)=delete
std::vector< std::jthread > threads
thread_pool(thread_pool &&)=default
thread_pool & operator=(thread_pool &&)=default
void pool_sync_run_all(F &&f)
Run a function on all threads in the global thread pool, synchronously waiting for all threads.
void pool_sync_run_n(I n, F &&f)
Run a function on the first n threads in the global thread pool, synchronously waiting for those thre...
void pool_set_num_threads(size_t num_threads)
Set the number of threads in the global thread pool.
std::optional< thread_pool > pool
std::condition_variable_any cv
std::function< void()> func
void run(std::stop_token stop)
std::exception_ptr exception