2020-03-28 00:39:22 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <queue>
|
|
|
|
|
#include <mutex>
|
|
|
|
|
#include <future>
|
|
|
|
|
|
|
|
|
|
class ThreadPool {
|
2023-07-26 04:56:50 +00:00
|
|
|
private:
|
|
|
|
|
std::condition_variable m_cond_var;
|
|
|
|
|
bool m_destruct_pool;
|
|
|
|
|
std::mutex m_mutex;
|
|
|
|
|
std::vector<std::thread> m_threads;
|
|
|
|
|
std::queue<std::function<void()>> m_work_queue;
|
2020-03-28 00:39:22 +00:00
|
|
|
|
2023-07-26 04:56:50 +00:00
|
|
|
public:
|
|
|
|
|
ThreadPool(unsigned int initial_pool_size);
|
|
|
|
|
~ThreadPool();
|
|
|
|
|
template <typename F, typename... Args>
|
|
|
|
|
inline auto SubmitWork(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
|
|
|
|
|
auto func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
|
|
|
|
|
auto task = std::make_shared<std::packaged_task<decltype(f(args...))()>>(std::forward<decltype(func)>(func));
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2023-08-15 03:50:14 +00:00
|
|
|
// wrap packed task into a void return function type so that it can be stored in queue
|
2023-07-26 04:56:50 +00:00
|
|
|
m_work_queue.push([task]() { (*task)(); });
|
2020-03-28 00:39:22 +00:00
|
|
|
}
|
2023-07-26 04:56:50 +00:00
|
|
|
|
2023-08-15 03:50:14 +00:00
|
|
|
m_cond_var.notify_one(); // unblocks one of the waiting threads
|
2023-07-26 04:56:50 +00:00
|
|
|
return task->get_future();
|
|
|
|
|
}
|
2020-03-28 00:39:22 +00:00
|
|
|
};
|