基于C++11 通用线程池
thread_pool.h
#ifndef _PTHREAD_H_
#define _PTHREAD_H_
#include <iostream>
#include <queue>
#include <vector>
#include <future>
class Pthread_Pool
{
public:
Pthread_Pool() : m_thread_size(1), m_terminate(false) {}
~Pthread_Pool() { thread_stop(); }
public:
// 线程池初始化
bool thread_init(size_t size);
// 启动线程池各个线程
bool thread_start();
// 停止所有线程
void thread_stop();
// 任务执行入口
template <class F, class... A>
auto exec(F&& f, A&&... args) -> std::future<decltype(f(args...))>;
private:
// 每个任务都是一个struct结构体,方便未来扩展
struct Task {
Task() {}
std::function<void()> m_func;
};
// Task未来在队列中以智能指针的形式传递
typedef std::shared_ptr<Task> task_func;
private:
// 尝试从任务队列获取一个任务
bool get_task(task_func& t);
// 线程主函数
void thread_run();
private:
std::queue<task_func> m_tasks; // 任务队列
std::vector<std::thread*> m_threads; // 线程池
std::mutex m_mutex; //锁
std::condition_variable m_cond; // 用于线程之间通知的条件变量
size_t m_thread_size; // 线程池大小
bool m_terminate; // 标记线程是否结束
std::atomic<int> m_atomic{0}; // 用于记录状态的原子变量
};
#endif _PTHREAD_H_
thread_pool.cpp
#include "pthread_pool.h"
// 线程池初始化
bool Pthread_Pool::thread_init(size_t size) {
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_threads.empty()) {
return false;
}
m_thread_size = size;
}
// 启动线程池各个线程
bool Pthread_Pool::thread_start() {
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_threads.empty()) {
return false;
}
for (size_t i = 0; i < m_thread_size; i++) {
m_threads.emplace_back(new std::thread(&Pthread_Pool::thread_run, this));
}
return true;
}
// 停止所有线程
void Pthread_Pool::thread_stop() {
{
std::unique_lock<std::mutex> lock(m_mutex);
m_terminate = true;
m_cond.notify_all();
}
for (auto& m_thread : m_threads) {
if (m_thread->joinable()) {
m_thread->join();
}
delete m_thread;
m_thread = nullptr;
}
std::unique_lock<std::mutex> lock(m_mutex);
m_threads.clear();
}
// 线程主函数
void Pthread_Pool::thread_run() {
while (!m_terminate) {
task_func task;
bool ok = get_task(task);
if (ok) {
++m_atomic;
task->m_func();
--m_atomic;
std::unique_lock<std::mutex> lock(m_mutex);
if (m_atomic == 0 && m_tasks.empty()) { // 是否所有任务都执行完成
m_cond.notify_all();
}
}
}
}
// 尝试从任务队列获取一个任务
bool Pthread_Pool::get_task(task_func& t) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_tasks.empty()) {
m_cond.wait(lock, [this] {return m_terminate || !m_tasks.empty(); });
}
if (m_terminate) return false;
t = std::move(m_tasks.front());
m_tasks.pop();
return true;
}
// 任务执行入口
template <class F, class... A>
auto Pthread_Pool::exec(F&& f, A&&... args) -> std::future<decltype(f(args...))> {
using retType = decltype(f(args...));
auto task = std::make_shared<std::packaged_task<retType>>(bind(std::forward<F>(f), std::forward<A>(args)...));
task_func f_ptr = std::make_shared<task>();
f_ptr->m_func = [task]() { (*task)(); };
std::unique_lock<std::mutex> lock(m_mutex);
m_tasks.push(f_ptr);
m_cond.notify_one();
return task->get_future();
}
main.cpp
#include "pthread_pool.h"
#include <iostream>
using namespace std;
void threadFunc(int a) {
cout << "a=" << a << endl;
}
class A {
public:
A() = default;
int run(int a, int b) {
return a + b;
}
};
int main() {
Pthread_Pool p1;
p1.thread_init(10);
p1.thread_start();
p1.exec(threadFunc, 100);
p1.exec(threadFunc, 200);
A a1;
auto fu1 = p1.exec(std::bind(&A::run, &a1, std::placeholders::_1, std::placeholders::_2), 10, 20);
int ret = fu1.get();
std::cout << "res:" << ret << std::endl;
p1.thread_stop();
return 0;
}