C++实现简单的线程池

        最近在学习音视频的时候,解封装和解码的时候用到了多线程。于是把线程池的知识补了一下。

        线程池的这个知识点有会涉及到锁,生产者消费者设计模式,纯虚函数继承等知识。在学习的时候可以根据知识点扩展延伸。

        楼主在学习线程池这部分的时候没有更进一步深入。比如负载均衡,贪心算法,退火算法等这些都没有去研究。一来是楼主目前的数学基础还很孱弱,二来还用不到高并发的场景。

        代码部分也为楼主网上学习,欢迎大家在评论区交流讨论。

        

这里的思路是先初始化线程池内线程,在Start函数中启动线程池的Run函数,在线程池的run函数内通过while循环让线程不是在工作就是在等待工作的路上。

因为在Start函数中new了很多个线程,所以这里引入了deque容器对其维护,因为使用了容器,所以使用锁对这个容器维护,因为使用了锁,不妨借用栈的特性加类的构造函数和析构函数的特性。所以这里使用了 unique_lock<mutex> unique(mux);

本着测试先行的原则,完成这部分就可以测试Start函数了。

线程部分解决了,接下来是任务部分。留出接口AddTask() 给外部,GetTask()给工作的线程获取线程。这里考虑到FIFO的调度,选用了deque容器来维护外部添加的Task。添加任务和获取任务通过信号量 condition_variable来实现。

代码如下

ThreadPool.h部分

#pragma once#include <atomic>						//原子变量,不用设置互斥锁
#include <thread>
#include <deque>						//考虑到后面的FIFO调度,这里使用这个容器
#include <mutex>
#include <condition_variable>class Task {
public:virtual void Run() = 0;				//纯虚函数,自定义函数继承,将需要多线程的操作放在这个Run函数中实现
};class ThreadPool
{
public:void initThread(int _nums);void Start();void Stop();void AddTask(Task* _task);Task* GetTask();private:void Run();std::atomic<int> threadNums;		//头文件中不使用命名空间std::deque<std::thread*> threadVec;		std::deque<Task*>		 taskVec;	std::mutex mux;std::atomic<bool> is_exit = false;  //退出标志位std::condition_variable cv;			//信号量};

ThreadPool.cpp部分

#include "ThreadPool.h"
#include <iostream>using namespace std;void ThreadPool::initThread(int _nums)
{threadNums = _nums;
}void ThreadPool::Start()
{if (threadNums <= 0){cerr << "Please Init threadNums" << endl;		//相对于cout ,cerr不占用缓存return;}//因为对容器进行了操作,防止串台,加一个锁unique_lock<mutex> unique(mux);						//相当于实例化一个对象,通过栈里面对象会自动销毁,//在构造和析构函数中完成了加锁出作用域后自动解锁 if (!threadVec.empty())		//因为有容器维护,所以这里判断是否为空来判断是否多次start{cerr << "has been Inited it" << endl;return;}for (int i = 0; i < threadNums; i++){thread* th = new thread(&ThreadPool::Run, this);	//库函数thread的构造函数,这里传入的是类成员函数,有细节//创建好线程,使用容器维护threadVec.push_back(th);}
}//退出线程池函数
void ThreadPool::Stop()
{//首先暂停while循环条件is_exit = true;//通知正在等待任务的线程cv.notify_all();//等待还在运行的线程结束for (auto th : threadVec){th->join();			//等待线程运行结束delete th;}//清理维护线程池的容器unique_lock<mutex> unique(mux);threadVec.clear();}void ThreadPool::AddTask(Task* _task)
{unique_lock<mutex> unique(mux);taskVec.push_back(_task);unique.unlock();cv.notify_one();
}Task* ThreadPool::GetTask()
{unique_lock<mutex> unique(mux);if (taskVec.empty()){cv.wait(unique);}if (is_exit){return nullptr;}Task* _task = taskVec.front();taskVec.pop_front();		//FIFOreturn _task;
}void ThreadPool::Run()
{//线程池中每个线程在退出前都一直在等待这个循环while (!is_exit){Task* task = GetTask();task->Run();}}

 main.cpp (测试代码部分)

#include <iostream>
#include "ThreadPool.h"using namespace std;class myTask :public Task
{
public:void Run() override{cout << "hello world" << endl;this_thread::sleep_for(1s);		//模拟任务耗时}};int main()
{ThreadPool pool;pool.initThread(1);pool.Start();myTask a_task;myTask b_task;pool.AddTask(&a_task);pool.AddTask(&b_task);this_thread::sleep_for(3s);		//这里不等待不会执行任务,直接退出。还请评论区大佬指点一二pool.Stop();getchar();		//阻塞观察线程运行现象return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10 -力扣高频 SQL 50 题(基础版)

10 - 每台机器的进程平均运行时间 -- sum(if(activity_type end,timestamp ,-timestamp )) -- 如果activity_type为“end”,值为timestamp&#xff0c;为“start” 为-timestamp&#xff0c;所有数相加end-start -- count(distinct process_id),获取同一机器有几个进行id -- r…

鸿蒙HarmonyOS实战—如何使用Video组件播放视频

1.视频播放 鸿蒙系统中&#xff0c;关于视频播放&#xff0c;可以使用上层视频组件Video。 参数如下 src 支持file:///data/storage路径前缀的字符串&#xff0c;用于读取应用沙箱路径内的资源。需要保证目录包路径下的文件有可读权限。 说明&#xff1a;视频支持的格式是&am…

为何限定项目的 Node.js 版本

首先区分三个概念nvm&#xff0c;npm&#xff0c;nodejs。 Node.js: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境。它允许开发者使用 JavaScript 在服务器端编写应用程序,而不仅限于在浏览器中运行 JavaScript。Node.js 提供了一系列内置的模块和 API,使得开发…

Python中数字比较与获取较大值的深入解析

目录 一、引言 二、Python数字类型概述 三、数字比较操作符 四、获取较大值的逻辑与实现 五、高级话题&#xff1a;使用内置函数和库 六、性能分析与优化 七、案例分析 八、总结与展望 一、引言 在编程世界中&#xff0c;数字的比较和获取较大值是基础且常见的操作。P…

Java 获取和修改期日与时间的各种操作方法

LocalDateTime获取当地日期和时间 import java.time.LocalDateTime; /*LocalDateTime.now() 获取当前时间*/ public class LocalDateTimeDemo {public static void main(String[] args) {LocalDateTime time1 LocalDateTime.now();System.out.println(time1);//2024-06-01T13…

【python】flask相关包依赖关系问题

【背景】 做flask项目时&#xff0c;由于涉及多个包&#xff0c;比如flask&#xff0c;flask-wtf&#xff0c;werkqeug等&#xff0c;不同版本情况下&#xff0c;互相依赖关系的确实会导致报错。比如报某个依赖无法从flask的相关包中导入等。 【解决办法】 实测可用版本搭配…

四川景源畅信:抖音做直播有哪些人气品类?

随着互联网科技的飞速发展&#xff0c;抖音作为新兴的社交媒体平台&#xff0c;已经成为了人们日常生活中不可或缺的一部分。而在抖音平台上&#xff0c;直播功能更是吸引了大量的用户和观众。那么&#xff0c;在抖音上做直播有哪些人气品类呢?接下来&#xff0c;就让我们一起…

目标检测数据集 - 智能零售柜商品检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;智能零售柜商品检测数据集&#xff0c;真实智能零售柜监控场景采集高质量商品图片数据&#xff0c;数据集含常见智能零售柜商品图片&#xff0c;包括罐装饮料类、袋装零食类等等。数据标注标签包含 113 个商品类别&#xff1b;适用实际项目应用&#xff…

C++的爬山算法

爬山算法&#xff08;Hill Climbing Algorithm&#xff09;是一种局部搜索算法&#xff0c;它通过迭代搜索的方式寻找问题的局部最优解。在爬山过程中&#xff0c;算法总是选择当前状态邻域中最好&#xff08;即函数值最大或最小&#xff09;的状态作为下一个状态&#xff0c;直…

直播美颜插件详解:美颜SDK的技术原理

美颜SDK作为实现美颜功能的核心技术&#xff0c;已被广泛应用于各种直播和短视频应用中。那么&#xff0c;美颜SDK究竟是如何工作的&#xff1f;它背后的技术原理又是什么&#xff1f;本文将对直播美颜插件及其技术原理进行详解。 一、美颜SDK的概述 美颜SDK包含了各种图像处…

⌈ 传知代码 ⌋ 微表情识别系统

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

C++ Thread多线程并发记录(3)线程创建总结

1.启动线程传递全局函数 #include <iostream> #include <thread>void Th1(int id){std::cout << "Create global fun. id " << id << std::endl; } void TH1(const int &id){std::cout << "Create global fun. id &…

软件质量保障复习

注&#xff1a;&#xff08;红色字体是作业题&#xff09; 一、软件全方位缺陷检测 1.什么是软件&#xff1f; 2.什么是软件质量&#xff1f; 3.什么是软件缺陷&#xff1f; 4.软件缺陷有哪些类型&#xff1f;&#xff08;软件缺陷的表现&#xff09; 5.为什么需要软件全…

leetcode74搜索二维矩阵

题目 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 fa…

推荐系统三十六式学习笔记:原理篇.内容推荐|04|画鬼容易画人难:用户画像的“能”和“不能”

目录 什么是用户画像&#xff1f;用户画像的关键因素用户画像构建的方法总结&#xff1a; 今天我来跟你聊一聊用户画像那些事。 什么是用户画像&#xff1f; 用户画像对应的英文是User Profile ,它原本用于营销领域。营销人员需要对营销的客户有更精准的认识&#xff0c;从而能…

NeuralForecast 推理 - 最简单的推理方式

NeuralForecast 推理 - 最简单的推理方式 flyfish 最简单的保存和加载模型代码 import pandas as pd import numpy as npAirPassengers np.array([112.0, 118.0, 132.0, 129.0, 121.0, 135.0, 148.0, 148.0, 136.0, 119.0],dtypenp.float32, )AirPassengersDF pd.DataFram…

培养核心人才,落实IPD体系

IPD体系已经成为业界公认的研发管理优秀框架与实践&#xff0c;不过在企业范围内&#xff0c;真正落实IPD体系、并且取得收益&#xff0c;却并非一件容易的事情&#xff0c;流程体系建立好了&#xff0c;却发现找不到合适人员去落实&#xff0c;任命了相关团队和成员&#xff0…

大文件上传处理:分卷压缩

大文件上传处理&#xff1a;分卷压缩 大文件上传处理&#xff1a;分卷压缩1、分卷压缩&#xff08;1&#xff09;Bandizip压缩工具&#xff1a;&#xff08;2&#xff09;分卷压缩后&#xff1a; 2、分卷压缩解压3、解压缩工具下载 大文件上传处理&#xff1a;分卷压缩 1、分卷…

第 400 场 LeetCode 周赛题解

A 候诊室中的最少椅子数 计数&#xff1a;记录室内顾客数&#xff0c;每次顾客进入时&#xff0c;计数器1&#xff0c;顾客离开时&#xff0c;计数器-1 class Solution {public:int minimumChairs(string s) {int res 0;int cnt 0;for (auto c : s) {if (c E)res max(res, …

i.MX8MP平台开发分享(TMU功能介绍篇)

概述 温度监控单元&#xff08;TMU&#xff09;监控并报告来自一个或多个芯片上远程温度测量点的温度。温度管理单元的特性&#xff1a; 温度测量范围&#xff1a;-40至105C。监控功能&#xff1a; 单点或多点监控超出范围指示高/低温度范围监控即时和平均温度监控可编程低通…