此处不多介绍 自行了解C++11的新特性
#pragma once
#include <vector>
#include <queue>
#include <atomic>
#include <future>
#include <condition_variable>
#include <thread>
#include <functional>
#include <stdexcept>
using namespace std;
using Task = function<void()>; //定义类型
#define THREADPOOL_MAX_NUM 16
class Threadpool
{
public:
Threadpool(unsigned short size = 4);
~Threadpool();
template<class F, class... Args>
auto Commit(F&& f, Args&&... args)->future < decltype(f(args...))>
{
if (!m_Run) throw runtime_error("commit on ThreadPool is stopped.");
using RetType = decltype(f(args...));
auto taskPtr = make_shared<packaged_task<RetType()>>(bind(forward< F >(f), forward< Args >(args)...));
lock_guard< mutex > lock(m_Lock);//对当前块的语句加锁 lock_guard 是 mutex 的 stack 封装类,构造的时候 lock(),析构的时候 unlock()
std::function<void()> warpper_func = [taskPtr]()
{
(*taskPtr)();
};
m_TasksQueue.emplace(warpper_func);
if (_idlThrNum < 1 && _pool.size() < THREADPOOL_MAX_NUM)
addThread(1);
m_TaskCondVar.notify_one(); // 唤醒一个线程执行
return taskPtr->get_future();
}
int idlCount();
int threadCount();
void addThread(unsigned short size);
void worker();
private:
vector<thread> m_PoolList; //线程池
queue<Task> m_TasksQueue; //任务队列
mutex m_Lock; //同步
condition_variable m_TaskCondVar; //条件阻塞
atomic<bool> m_Run = true; //线程池是否执行
atomic<int> m_idlThrNum = 0; //空闲线程数量
};
#include "Pool.h"
Threadpool::Threadpool(unsigned short size /*= 4*/)
{
addThread(size);
}
Threadpool::~Threadpool()
{
m_Run = false;
m_TaskCondVar.notify_all(); //唤醒所有线程执行
for (thread& thread : m_PoolList)
{
if (thread.joinable())
{
thread.join(); // 等待任务结束, 前提:线程一定会执行完
}
}
}
int Threadpool::idlCount()
{
return m_idlThrNum;
}
int Threadpool::threadCount()
{
return m_PoolList.size();
}
void Threadpool::addThread(unsigned short size)
{
for (; m_PoolList.size() < THREADPOOL_MAX_NUM && size > 0; --size)
{
m_PoolList.emplace_back(&Threadpool::worker, this);
}
}
void Threadpool::worker()
{
unique_lock< mutex > lock(m_Lock);
m_TaskCondVar.wait(lock, [this] {return !m_Run || !m_TasksQueue.empty(); }); // wait 直到有 task
if (!m_Run && m_TasksQueue.empty()) return;
Task task = move(m_TasksQueue.front());
m_TasksQueue.pop();
m_idlThrNum--;
lock.unlock();
task();
m_idlThrNum++;
}
函数调用
Threadpool executor(50);
auto func = [](int i)
{
if (i % 2) QThread::msleep(100);
qDebug() << "hello, fh ! " << QThread::currentThreadId() << "-------" <<i;
};
for (int i = 0; i < 20; i++)
{
std::future< void > fh = executor.Commit(func, i);
}