3#include <condition_variable>
20 std::condition_variable_any
cv;
23 std::vector<std::function<void()>>
funcs;
27 void work(std::stop_token stop,
size_t i) {
30 std::unique_lock lck{sig.mtx};
31 sig.cv.wait(lck, stop, [&] {
return static_cast<bool>(
funcs[i]); });
32 if (stop.stop_requested()) {
48 explicit thread_pool(
size_t num_threads = std::thread::hardware_concurrency())
51 for (
size_t i = 0; i < num_threads; ++i)
53 [
this, i](std::stop_token stop) { this->
work(std::move(stop), i); });
61 void schedule(
size_t i, std::function<
void()> func) {
63 std::unique_lock lck{sig.mtx};
64 funcs[i] = std::move(func);
71 std::unique_lock lck{sig.mtx};
72 sig.cv.wait(lck, [&] {
return !
funcs[i]; });
74 std::rethrow_exception(std::exchange(e,
nullptr));
78 for (
size_t i = 0; i <
size(); ++i)
82 template <
class I =
size_t,
class F>
84 const auto n =
size();
85 for (
size_t i = 0; i < n; ++i)
86 schedule(i, [&f, i, n] { f(
static_cast<I
>(i),
static_cast<I
>(n)); });
90 template <
class I =
size_t,
class F>
92 if (
static_cast<size_t>(n) >
size())
93 throw std::invalid_argument(
"Not enough threads in pool");
94 for (
size_t i = 0; i < static_cast<size_t>(n); ++i)
95 schedule(i, [&f, i, n] { f(
static_cast<I
>(i), n); });
96 for (
size_t i = 0; i < static_cast<size_t>(n); ++i)
105extern std::optional<thread_pool>
pool;
116template <
class I =
size_t,
class F>
128template <
class I =
size_t,
class F>
void sync_run_n(I n, F &&f)
thread_pool & operator=(const thread_pool &)=delete
std::vector< Signals > signals
std::vector< std::exception_ptr > exceptions
std::condition_variable_any cv
thread_pool(size_t num_threads=std::thread::hardware_concurrency())
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
std::vector< std::function< void()> > funcs
thread_pool & operator=(thread_pool &&)=default
void work(std::stop_token stop, size_t i)
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