c++ 实现线程池ThreadPool
参考github thttps://github.com/mtrebi/thread-pool
里面很详细的介绍了需要的一些比较少用的语法知识
// Submit a function to be executed asynchronously by the pool
template<typename F, typename...Args>
auto submit(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
// Create a function with bounded parameters ready to execute
std::function<decltype(f(args...))()> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
// Encapsulate it into a shared ptr in order to be able to copy construct / assign
auto task_ptr = std::make_shared<std::packaged_task<decltype(f(args...))()>>(func);
// Wrap packaged task into void function
std::function<void()> wrapper_func = [task_ptr]() {
(*task_ptr)();
};
// Enqueue generic wrapper function
m_queue.enqueue(wrapper_func);
// Wake up one thread if its waiting
m_conditional_lock.notify_one();
// Return future from promise
return task_ptr->get_future();
}
};
原文中介绍相应的c++背景知识已经很清晰了,所以这里只做一些简单的概括:
1. auto submit(F&& f, Args&&... args) -> std::future<decltype(f(args...))> 是在函数返回类型未定义时使用的, 它的返回类型就是 td::future<decltype(f(args...))> ;
2. std::function<decltype(f(args...))()> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...); 是一个包装器(wrapper),它可以封装函数,在需要的时候执行它,后面把它封装在一个shared_ptr里
3. std::function<void()> wrapper_func = [task_ptr]() (*task_ptr)(); }; 是为了将代码储在m_queue里做的规范,也是一个包装器(wrapper)
class ThreadWorker { private: int m_id; ThreadPool * m_pool; public: ThreadWorker(ThreadPool * pool, const int id) : m_pool(pool), m_id(id) { } void operator()() { std::function<void()> func; bool dequeued; while (!m_pool->m_shutdown) { { std::unique_lock<std::mutex> lock(m_pool->m_conditional_mutex); if (m_pool->m_queue.empty()) { m_pool->m_conditional_lock.wait(lock); } dequeued = m_pool->m_queue.dequeue(func); } if (dequeued) { func(); } } } };
接下来介绍一下这个,这个是放在线程池里的线程,在ThreadPool初始化之后,会把一直执行它,它会一直检索m_queue里的任务,然后不断地执行m_queue里的func

浙公网安备 33010602011771号