版本一:
轮子:https://blog.csdn.net/zdarks/article/details/46994607#commentBox
下面稍微改造了一下
不明白,可以看我上一篇:https://blog.csdn.net/chicaidecaiji/article/details/112723515
-
main.cpp
#include "ThreadPool.h"
#include <iostream>
char Func(char c) {
int cnt = 1;
while(cnt < 10) {
std::cout<< c<< std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
cnt++;
}
return c;
}
struct G{
int operator()(){
std::cout << "hello, go !" << std::endl;
return 42;
}
};
int main(int argc, char **argv) {
try {
ThreadPool pool(10);
pool.start();
auto fut1 = pool.commit(Func, 'A');
std::this_thread::sleep_for(std::chrono::seconds(1));
auto fut2 = pool.commit(Func, 'B');
// pool.shutdown();
auto fut3 = pool.commit(Func, 'C');
auto fut4 = pool.commit(Func, 'D');
auto fut5 = pool.commit(Func, 'E');
// pool.start();
auto fut6 = pool.commit(G{});
std::cout<<"fut1.get() :"<< fut1.get()<< std::endl;
std::cout<<"fut2.get() :"<< fut2.get()<< std::endl;
std::cout<<"fut3.get() :"<< fut3.get()<< std::endl;
std::cout<<"fut4.get() :"<< fut4.get()<< std::endl;
std::cout<<"fut5.get() :"<< fut5.get()<< std::endl;
std::cout<<"fut6.get() :"<< fut6.get()<< std::endl;
} catch(std::exception& e){
std::cout << "some unhappy happened... " << e.what() << std::endl;
}
return 0;
}
-
ThreadPool.h
#include <deque>
#include <functional>
#include <vector>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <atomic>
#include <future>
#include <queue>
class ThreadPool {
private:
using Task = std::function<void()>;
std::vector<std::thread> pool;
std::queue<Task> tasks;
std::condition_variable cv;
std::mutex mux;
std::atomic_bool state;
public:
ThreadPool(unsigned int sz);
~ThreadPool();
template<typename F, typename... Agrs>
auto commit(F&& f, Agrs&&... args) -> std::future<decltype(f(args...))> {
using ResType = decltype(f(args...));
std::shared_ptr<std::packaged_task<ResType()>> task
= std::make_shared<std::packaged_task<ResType()>>(std::bind(f, args...));
// = std::make_shared<std::packaged_task<ResType()>>(std::bind(std::forward<F>(f), std::forward<Agrs>(args)...));
{
std::lock_guard<std::mutex> lock(mux);
tasks.emplace([task]() {
(*task)();
});
}
cv.notify_all();
std::future<ResType> future = task->get_future();
return future;
}
void shutdown();
void start();
private:
void schedule();
Task getOneTask();
};
-
ThreadPool.cpp
#include "ThreadPool.h" #include <iostream> #include <chrono> ThreadPool::ThreadPool(unsigned int sz) : state(false) { if(!sz) sz = 1; // 至少有一个线程 for(unsigned int i = 0; i < sz; i++) { pool.emplace_back(&ThreadPool::schedule, this); } } ThreadPool::~ThreadPool() { for(std::thread& thd : pool) { thd.detach(); } } ThreadPool::Task ThreadPool::getOneTask() { std::unique_lock<std::mutex> lock(mux); cv.wait(lock, [&]() { return state.load() && !tasks.empty(); }); Task task = tasks.front(); tasks.pop(); return task; } void ThreadPool::schedule() { while(true) { Task task = getOneTask(); task(); } } void ThreadPool::shutdown() { std::lock_guard<std::mutex> lock(mux); state.store(false); } void ThreadPool::start() { { std::lock_guard<std::mutex> lock(mux); state.store(true); } cv.notify_all(); }
版本二:
-
#include <atomic> #include <queue> #include <functional> #include <future> #include <iostream> #include <thread> #include <vector> template<typename T> class SafeDeque { public: SafeDeque(){}; ~SafeDeque(){}; void push(const T& t) { std::lock_guard<std::mutex> lock(mutex_); list_.push(t); } bool pop(T* t) { std::lock_guard<std::mutex> lock(mutex_); if (list_.empty()) { return false; } *t = std::move(list_.front()); list_.pop(); return true; } private: std::mutex mutex_; std::queue<T> list_; }; class ThreadPool { using Type = std::function<void()>; public: explicit ThreadPool(unsigned int thread_num); template <typename F, typename... Args> auto AddTask(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>; ~ThreadPool(); private: std::vector<std::thread> workers_; SafeDeque<Type> tasks_; std::atomic_bool stop_; }; ThreadPool::ThreadPool(unsigned int thread_num) : stop_(false) { while (thread_num--) { workers_.emplace_back([&] { while (!stop_) { Type task; if (tasks_.pop(&task)) { task(); } } }); } } ThreadPool::~ThreadPool() { workers_.clear(); stop_ = true; } template <typename F, typename... Args> auto ThreadPool::AddTask(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<F>(f), std::forward<Args>(args)...)); if (stop_) { return std::future<return_type>(); } tasks_.push([task] { (*task)(); }); return task->get_future(); } void A(int a) { std::cout << std::this_thread::get_id() << " " << a << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } void B(int b) { std::cout << std::this_thread::get_id() << " " << b << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } class CC { public: void C(int c) { std::cout << std::this_thread::get_id() << " " << c << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } }; int main() { ThreadPool pool(10); int a = 0; int b = 1000; int c = 2000000; CC cc; while (a < 100) { pool.AddTask(A, a++); pool.AddTask(B, b++); pool.AddTask(&CC::C, cc, c++); } getchar(); }