c++ 线程池
#include<thread>
#include<mutex>
#include<functional>
#include<condition_variable>
#include<vector>
#include<queue>
class ThreadPool {
std::mutex mtx;
std::mutex cntMtx;
std::condition_variable condition;
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
bool stop = false;
volatile int cnt = 0;
//volatile 避免被编译器优化掉
public:
ThreadPool(int nums = 8) {
for (int i = 0; i < nums; i++) {
threads.emplace_back([this]() -> void {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
//获得锁的所有权
condition.wait(lock, [this] {return !tasks.empty() || stop; });
if (stop && tasks.empty())return;
std::function<void()> task = std::move(tasks.front());
tasks.pop();
lock.unlock();
//可以并发执行
task();
lock.lock();
cnt--;
//
}
});
}
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(mtx);
stop = true;
//{}的作用是创建作用域便于std::unique_lock析构
}
condition.notify_all();
for (auto& thread : threads) {
thread.join();
}
}
void waitEnd() {
while (true) {
if (cnt == 0)return;
//volatile 避免被编译器优化掉
}
}
template<class F, class ...Args>
void add(F&& f, Args&& ...args) {
std::function<void()> task(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
//万能引用和完美转发
{
std::unique_lock<std::mutex> lock(mtx);
tasks.emplace(std::move(task));
cnt++;
}
condition.notify_one();
//唤醒线程执行任务
}
};
如果有并发队列还存在另一种形式
#pragma once
#include <atomic>
#include <thread>
#include <memory>
#include <vector>
#include <functional>
#include <concurrent_queue.h>
//使用Microsoft的concurrent_queue
class ThreadPool {
public:
ThreadPool(size_t numThreads) : stop(false) {
for (size_t i = 0; i < numThreads; ++i) {
workers.emplace_back([this] {
while (true) {
if (stop.load() == true) return;
if (tasks.empty())continue;
std::function<void()>task;
while (!tasks.try_pop(task));
if (task == nullptr)return;
task();
cnt--;
}
});
}
}
~ThreadPool() {
stop = true;
for (auto& worker : workers) {
tasks.push(nullptr); // 使用一个特殊值唤醒所有线程
}
for (std::thread& worker : workers) {
worker.join();
}
}
template<class F, class ...Args>
void add(F&& f, Args&& ...args) {
std::function<void()> task(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
tasks.push(std::move(task));
cnt++;
}
void wait() volatile {
while (true) {
int cur_cnt = cnt.load();
if (cur_cnt == 0)return;
}
}
private:
Concurrency::concurrent_queue<std::function<void()>> tasks;
std::vector<std::thread> workers;
std::atomic<bool> stop;
std::atomic<int> cnt;
};
对于性能暂未测试