又有了新思路,复用线程,学以致用——C++线程池
ThreadPool.hpp
#pragma once
#include <thread>
#include <memory>
#include <functional>
#include <utility>
#include <condition_variable>
#include <atomic>
#include <queue>
#include <vector>
#include <future>
class ThreadAdapter {
protected:
bool stop = false;
std::shared_ptr<std::thread> m_t;
/**
* @brief 子线程阻塞锁
*
*/
std::mutex m_mutex;
public:
enum class ThreadStatus {
WAIT,
RUNNING,
};
std::atomic<ThreadStatus> status = ThreadStatus::WAIT;
explicit ThreadAdapter(std::queue<std::function<void()>> &fq, std::condition_variable &cv, std::mutex &fqM) {
m_t = std::make_shared<std::thread>([this, &q = fq, &c = cv, &m = fqM]() {
while (!stop) {
std::function<void()> fun;
while (true) {
{
std::unique_lock<std::mutex> l(m);
if (!q.empty()) {
fun = q.front();
q.pop();
break;
}
}
std::unique_lock<std::mutex> lock(m_mutex);
c.wait(lock);
}
this->status = ThreadStatus::RUNNING;
if (fun) {
fun();
}
this->status = ThreadStatus::WAIT;
c.notify_all();
}
});
}
void Detach() {
if (this->status != ThreadStatus::WAIT && m_t->joinable()) {
this->stop = true;
m_t->detach();
}
}
~ThreadAdapter() {
if (this->status != ThreadStatus::WAIT && m_t->joinable()) {
this->stop = true;
m_t->join();
}
}
};
class ThreadPool {
protected:
std::queue<std::function<void()>> fq;
std::mutex fqM;
std::condition_variable cv;
std::vector<std::shared_ptr<ThreadAdapter>> t;
public:
explicit ThreadPool(int s) {
for (int i = 0; i < s; ++i) {
auto p = std::make_shared<ThreadAdapter>(fq, cv, fqM);
t.emplace_back(std::move(p));
}
}
/**
* @brief 主要核心思想就这一个模板函数,用于将原始函数封装成
*
* @tparam F 目标函数类型
* @tparam Args 函数的参数类型
* @param func 目标函数
* @param args 目标参数
* @return decltype(auto) 自动推导返回值
*/
template<typename F, typename... Args>
decltype(auto) AddTask(F &&func, Args &&...args) {
//推导最后的返回值类型
using res_type = typename std::result_of<F(Args...)>::type;
//封装为packaged_task的智能指针类型
auto task = std::make_shared<std::packaged_task<res_type()>>(
std::bind(std::forward<F>(func), std::forward<Args>(args)...));
//获取用于异步获取返回值的future
std::future<res_type> res = task->get_future();
{
{
std::unique_lock<std::mutex> lock(fqM);
fq.emplace([task]() { (*task)(); });
}
cv.notify_one();
}
return res;
}
};
test.cpp#
#include <iostream>
#include <thread>
#include "ThreadPool.hpp"
#include <atomic>
using namespace std;
int main() {
ThreadPool threadPool(10);
mutex m;
std::atomic<int> at = 0;
for (int i = 0; i < 100000; ++i) {
threadPool.AddTask([&a = at]() {
for (int j = 0; j < 1000; ++j) {
a++;
}
});
}
for (int i = 0; i < 100; ++i) {
cout << at << endl;
std::this_thread::sleep_for(std::chrono::milliseconds (1));
}
std::this_thread::sleep_for(std::chrono::minutes(100));
return 0;
}
作者:Esofar
出处:https://www.cnblogs.com/WindSnowLi/p/16998171.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类