C++ 封装线程池(结合QT支持信号机制)

server/2024/9/23 4:06:21/

纯C++风格线程池

纯C++ 风格线程池可参考这篇文章

https://llfc.club/category?catid=225RaiVNI8pFDD5L4m807g7ZwmF#!aid/2c2IJUcCUOfzEQQRRdOXYIZuCjP

视频教程

相关线程池和并发编程的视频可以看看这个连接:

https://www.bilibili.com/video/BV1Xt421H7M7/?vd_source=8be9e83424c2ed2c9b2a3ed1d01385e9

支持信号机制的线程池

我的项目中期待封装一个类,内部有个线程池处理外部投递的内容,这个类同时支持对外发送信号等,同时这个类是一个单例类,那么这个类可以继承QOjbject支持信号机制,并且其内部可以封装一个线程池响应外部投递的任务,结合纯C++版本封装了如下在QT环境使用的线程池,目前已经投入到生产中。

用到的头文件

#include <QObject>
#include <queue>
#include <vector>
#include <thread>
#include <queue>
#include <memory>
#include <functional>
#include <mutex>
#include <atomic>
#include <future>

头文件编写

#ifndef SEQSCHEDULER_H
#define SEQSCHEDULER_H
//wwc 处理维护,关机流程,清洗等时序执行的类
class SeqScheduler: public QObject
{Q_OBJECT
public:~ SeqScheduler();static SeqScheduler& Inst();template<typename F, typename ... Args>auto CommitTask(F&& func, Args && ... args) ->std::future<decltype(std::forward<F>(func)(std::forward<Args>(args)...))> {using RetType = decltype(std::forward<F>(func)(std::forward<Args>(args)...));if (_b_stop.load()) {return std::future<RetType>{};}auto bind_func = std::bind(std::forward<F>(func), std::forward<Args>(args)...);auto pack_task = std::make_shared<std::packaged_task<RetType(void)>>(bind_func);auto future = pack_task->get_future();{std::lock_guard<std::mutex> lock(_work_mtx);_work_que.push([pack_task]() {(*pack_task)();});}_work_con.notify_one();return future;}private: SeqScheduler(const SeqScheduler&) = delete;SeqScheduler& operator = (const SeqScheduler&) = delete;SeqScheduler(unsigned int num = std::thread::hardware_concurrency());std::queue<std::function<void(void)>> _work_que;std::mutex _work_mtx;std::condition_variable _work_con;std::atomic<bool>  _b_stop;std::vector<std::thread> _pool;std::atomic_int          _thread_num;
};#endif // SEQSCHEDULER_H

类的具体实现

#include "seqscheduler.h"SeqScheduler::SeqScheduler(unsigned int num ): _b_stop(false)
{if (num <= 1)_thread_num = 1;else_thread_num = num;for (int i = 0; i < _thread_num; i++) {_pool.emplace_back([this]() {for (; !(_b_stop.load());) {std::unique_lock<std::mutex> unique_locker(_work_mtx);_work_con.wait(unique_locker, [this]() {if (_b_stop.load()) {return true;}if (_work_que.empty()) {return false;}return true;});if (_b_stop.load()) {return;}//出队auto task = _work_que.front();_work_que.pop();unique_locker.unlock();task();}});}}SeqScheduler& SeqScheduler::Inst()
{static SeqScheduler inst;return inst;
}SeqScheduler::~SeqScheduler(){_b_stop = true;{std::unique_lock<std::mutex> unique_locker(_work_mtx);_work_con.notify_all();}for (auto& td : _pool) {if (td.joinable()) {std::cout << "join thread " << td.get_id() << std::endl;td.join();}}
}

使用线程池

线程池的使用可以通过如下方式投递任务,任务在后台自动执行

void Test(){SeqScheduler::Inst().CommitTask([]() {asyncLog("slot machine perfusion called ");});
}

如需等待任务完成,可以用wait或者get

void Test(){auto task_future = SeqScheduler::Inst().CommitTask([]() {asyncLog("slot machine perfusion called ");});task_future.wait();
}

http://www.ppmy.cn/server/46280.html

相关文章

前端一个页面依赖多个接口解决之node接口聚合

首先先介绍一下页面的接口请求处理&#xff1a; 接口请求之间是否存在依赖性&#xff0c;主要有两种处理方式&#xff1a; 并行请求&#xff1a; 当这些接口彼此之间互不依赖时&#xff0c;可以同时发起多个请求。这时可以使用 Promise.all([…]) 来处理&#xff0c;这样可以…

“米线大王”蒙自源,隆重上新儿童餐

人间烟火气&#xff0c;最抚凡人心。在饥肠辘辘时&#xff0c;你是否会选择来上一碗热气腾腾、香飘四溢的蒙自源米线呢&#xff1f;六月的微风不仅带来了夏日的温柔&#xff0c;也带来了蒙自源的新品——专为儿童设计的儿童餐&#xff0c;为大小朋友们带来了一场充满陪伴与享受…

RabbitMQ(Direct 订阅模型-路由模式)的使用

文章目录 RabbitMQ&#xff08;Direct 订阅模型-路由模式&#xff09;一&#xff0c;Direct 订阅模型-路由模式介绍&#xff08;Routing&#xff09;二&#xff0c;使用1.添加依赖2.修改配置文件3.创建配置类4.注入RabbitMQ模版引擎5.消息的发送6.消息的接收(监听)7.设置回调函…

EasyExcel实现导入导出

EasyExcel实现导入导出 目录 EasyExcel实现导入导出1、使用场景2、特点3、使用1、使用EasyExcel进行写操作&#xff08;下载Excel&#xff09;1. 在pom文件中添加对应的依赖2. 创建实体类&#xff0c;和excel数据对应3. converter自定义转换器4、性别枚举类 5.普通导出6.多shee…

【Tlias智能学习辅助系统】03 部门管理 前后端联调

Tlias智能学习辅助系统 03 部门管理 前后端联调 前端环境 前端环境 链接&#xff1a;https://pan.quark.cn/s/8720156ed6bf 提取码&#xff1a;aGeR 解压后放在一个不包含中文的文件夹下&#xff0c;双击 nginx.exe 启动服务 跨域的问题已经被nginx代理转发了&#xff0c;所以…

电商物流查询解决方案助力提升消费者体验

截至2023年12月&#xff0c;中国网络购物用户规模达9.15亿人&#xff0c;占网民整体的83.8%。这一庞大的数字不仅展现了电子商务的蓬勃发展&#xff0c;也标志着数字零售企业营销战略的转变——从以产品和流量为核心&#xff0c;到用户为王的新阶段。因此&#xff0c;提升消费者…

基础—SQL—DQL(数据查询语言)聚合函数

一、引言 一般情况下&#xff0c;我们在进行分组查询的时候&#xff0c;一般配合着聚合函数来进行操作&#xff0c;所以先了解和学习聚合函数再学习和操作分组查询。 二、DQL—聚合函数 1、介绍 聚合函数指的是讲一列数据作为一个整体&#xff0c;进行纵向的计算。 2、常见…

panic 、asset、crash 的含义和区别

在编程中&#xff0c;“panic” 和 “assert” 都是用于处理错误和异常情况的机制&#xff0c;但在不同的编程语言和框架中有一些区别。 panic&#xff1a; 含义&#xff1a;通常表示程序发生了无法恢复的错误或异常情况&#xff0c;需要立即终止程序的执行。 用法&#xff1…