当前位置: 首页 > news >正文

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

纯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.lryc.cn/news/360387.html

相关文章:

  • c# 学习教程
  • 【ros2】入门
  • 网络安全基础技术扫盲篇 — 名词解释之“数据包“
  • 26 _ 虚拟DOM:虚拟DOM和实际的DOM有何不同?
  • C语言(内存函数)
  • JVM之【执行引擎】
  • maven部署到私服
  • Android精通值Fragment的使用 —— 不含底层逻辑(五)
  • apache大数据各组件部署搭建(超级详细)
  • Servlet搭建博客系统
  • NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件
  • Python 二叉数的实例化及遍历
  • 计算 x 的二进制表示中 1 的个数
  • 基于Vue的前端瀑布流布局组件的设计与实现
  • WinSW使用说明
  • SpringBoot 多模块 多环境 项目 单元测试
  • 网络安全法中的网络安全规定和措施
  • 一、搭建 Vue3 Admin 项目:从无到有的精彩历程
  • Qt | Qt 资源简介(rcc、qmake)
  • 对boot项目拆分成cloud项目的笔记
  • CTF本地靶场搭建——基于阿里云ACR实现动态flag题型的创建
  • 【面试经典150题】删除有序数组中的重复项
  • 太阳能辐射整车综合性能环境试验舱
  • JS脚本打包成一个 Chrome 扩展(CRX 插件)
  • js事件对象
  • 希捷硬盘怎么恢复数据? 5 个免费希捷数据恢复软件
  • Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:京东无人配送机器人
  • STM32作业实现(七)OLED显示数据
  • elementui el-tooltip文字提示组件弹出层内容格式换行处理
  • Python3 笔记:每天一个函数——str.join()