#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <vector>
#include <queue>
#include <atomic>
#include <future>
//#include <condition_variable>
//#include <thread>
//#include <functional>
#include <stdexcept>
//線程池最大容量,應儘量設小一點
#define THREADPOOL_MAX_NUM 16
//#define THREADPOOL_AUTO_GROW
//線程池,可以提交變參函數或拉姆達表達式的匿名函數執行,可以獲取執行返回值
//不直接支持類成員函數, 支持類靜態成員函數或全局函數,Opteron()函數等
class ThreadPool
{
typedef std::function<void()> Task; //定義類型
std::vector<std::thread> _pool; //線程池
std::queue<Task> _tasks; //任務隊列
std::mutex _lock; //同步
std::condition_variable _task_cv; //條件阻塞
std::atomic<bool> _run; //線程池是否執行
std::atomic<int> _idlThrNum; //空閒線程數量
public:
inline ThreadPool(unsigned short size = 4)
{
_run = true;
_idlThrNum = 0;
AddThread(size);
}
inline ~ThreadPool()
{
_run=false;
_task_cv.notify_all(); // 喚醒所有線程執行
for (std::thread& thread : _pool) {
//thread.detach(); // 讓線程“自生自滅”
if(thread.joinable())
thread.join(); // 等待任務結束, 前提:線程一定會執行完
}
}
public:
int IdlCount();
int ThreadCount();
template<class F, class... Args>
auto Commit(F&& f, Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type>;
private:
void AddThread(unsigned short size);
};
template<class F, class... Args>
auto ThreadPool::Commit(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>
{
if (!_run)
{
throw std::runtime_error("Commit on ThreadPool is stopped.");
}
typedef typename std::result_of<F(Args...)>::type return_type;
auto task = std::make_shared<std::packaged_task<return_type()> >( //指向F函數的智能指針
std::bind(std::forward<F>(f), std::forward<Args>(args)...) //傳遞函數進行構造
);
std::future<return_type> future = task->get_future();
{ // 添加任務到隊列
std::lock_guard<std::mutex> lock{ _lock };//對當前塊的語句加鎖 lock_guard 是 mutex 的 stack 封裝類,構造的時候 lock(),析構的時候 unlock()
_tasks.emplace([task](){ // push(Task{...}) 放到隊列後面
(*task)();
});
}
_task_cv.notify_one(); // 喚醒一個線程執行
return future;
}
#endif
#include "Base/ThreadPool.h"
//空閒線程數量
int ThreadPool::IdlCount()
{
return _idlThrNum;
}
//線程數量
int ThreadPool::ThreadCount()
{
return _pool.size();
}
void ThreadPool::AddThread(unsigned short size)
{
for (; _pool.size() < THREADPOOL_MAX_NUM && size > 0; --size)
{ //增加線程數量,但不超過 預定義數量 THREADPOOL_MAX_NUM
_pool.emplace_back( [this]{ //工作線程函數
while (_run)
{
Task task; // 獲取一個待執行的 task
{
// unique_lock 相比 lock_guard 的好處是:可以隨時 unlock() 和 lock()
std::unique_lock<std::mutex> lock{ _lock };
_task_cv.wait(lock, [this]{
return !_run || !_tasks.empty();
}); // wait 直到有 task
if (!_run && _tasks.empty())
return;
task = move(_tasks.front()); // 按先進先出從隊列取一個 task
_tasks.pop();
}
_idlThrNum--;
task();//執行任務
_idlThrNum++;
}
});
_idlThrNum++;
}
}