Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ------------------------thread_pool.h----------------------------
- #ifndef _THREAD_POOL_H_
- #define _THREAD_POOL_H_
- #include <functional>
- #include <future>
- #include <mutex>
- #include <queue>
- #include <thread>
- namespace standby_network
- {
- class ThreadPool
- {
- public:
- ThreadPool(uint8_t thread_count = 0);
- ThreadPool(const ThreadPool &) = delete;
- ThreadPool(ThreadPool &&move);
- ~ThreadPool();
- public:
- auto operator=(const ThreadPool &) -> const ThreadPool & = delete;
- auto operator=(ThreadPool &&move) -> const ThreadPool &;
- public:
- template<typename Func, typename ...Args>
- auto enqueue(const Func &func, Args &&... args) -> void
- {
- auto f = std::bind(func, std::forward(args)...);
- tasks_mut.lock();
- tasks.push([&f]()
- {
- f();
- });
- tasks_mut.unlock();
- }
- template<typename Func, typename ...Args>
- auto enqueue_task(const Func &func, Args &&... args) -> std::future<typename std::result_of<Func(Args...)>::type>
- {
- auto f = std::bind(func, std::forward<Args>(args)...);
- using RetType = typename std::result_of<Func(Args...)>::type;
- std::promise<RetType> p;
- std::future ret_val = p.get_future();
- auto helper = [&f](std::promise<RetType> &&p)
- {
- return [&f, &p]()
- {
- p.set_value(f());
- };
- };
- tasks_mut.lock();
- tasks.push(helper(std::move(p)));
- tasks_mut.unlock();
- return std::move(ret_val);
- }
- private:
- std::mutex tasks_mut;
- std::queue<std::function<void()>> tasks;
- std::vector<std::thread> workers;
- bool run;
- };
- } // namespace standby_network
- #endif // _THREAD_POOL_H_
- ------------------------thread_pool.cc------------------------
- #include "thread_pool.h"
- namespace standby_network
- {
- ThreadPool::ThreadPool(uint8_t thread_count) :
- run(true)
- {
- auto worker_count = (thread_count) ? thread_count : std::thread::hardware_concurrency();
- for(int i = 0; i < worker_count; i++)
- {
- workers.push_back(std::thread([this]() -> void
- {
- while(run)
- {
- tasks_mut.lock();
- if(!tasks.empty())
- {
- auto t = tasks.front();
- tasks.pop();
- tasks_mut.unlock();
- t();
- }
- else
- {
- tasks_mut.unlock();
- }
- }
- }));
- }
- }
- ThreadPool::ThreadPool(ThreadPool &&move) :
- ThreadPool()
- {
- std::lock_guard this_guard(tasks_mut), that_guard(move.tasks_mut);
- tasks = std::move(move.tasks);
- }
- ThreadPool::~ThreadPool()
- {
- run = false;
- for(auto &w : workers)
- {
- if(w.joinable())
- {
- w.join();
- }
- }
- }
- auto ThreadPool::operator=(ThreadPool &&move) -> const ThreadPool &
- {
- run = move.run;
- std::lock_guard this_guard(tasks_mut), that_guard(move.tasks_mut);
- std::swap(tasks, move.tasks);
- return *this;
- }
- } // namespace standby_network
- ---------------------------------test.cc----------------------------
- #include <iostream>
- #include <thread_pool.h>
- auto main() -> int
- {
- using namespace standby_network;
- ThreadPool tp;
- auto task = [](int a, int b) -> int
- {
- return a + b;
- };
- int task_count = 2;
- std::vector<std::future<int>> futures;
- while(task_count)
- {
- futures.push_back(tp.enqueue_task(task, task_count, task_count + 1));
- task_count--;
- }
- for(auto &f : futures)
- {
- if(f.valid())
- {
- f.wait();
- std::cout << f.get() << std::endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement