线程池的实现与应用
一、线程池
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
二、线程池的应用场景
1. 需要大量的线程来完成任务,且完成任务的时间比较短。WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。但对于长时间的任务,比如一个 Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.
4.线程池示例:
1. 创建固定数量线程池,循环从任务队列中获取任务对象,
2. 获取到任务对象后,执行任务对象中的任务接口.
三、代码
主线程发布任务,多线程获得任务,执行任务
(1)任务
Task.hpp#pragma once
#include <iostream>
#include <string>std::string opers="+-*/%";enum{DivZero=1,ModZero,Unknown
};class Task
{
public:Task(int x, int y, char op) : data1_(x), data2_(y), oper_(op), result_(0), exitcode_(0){}void run(){switch (oper_){case '+':result_ = data1_ + data2_;break;case '-':result_ = data1_ - data2_;break;case '*':result_ = data1_ * data2_;break;case '/':{if(data2_ == 0) exitcode_ = DivZero;else result_ = data1_ / data2_;}break;case '%':{if(data2_ == 0) exitcode_ = ModZero;else result_ = data1_ % data2_;} break;default:exitcode_ = Unknown;break;}}void operator ()(){run();}std::string GetResult(){std::string r = std::to_string(data1_);r += oper_;r += std::to_string(data2_);r += "=";r += std::to_string(result_);r += "[code: ";r += std::to_string(exitcode_);r += "]";return r;}std::string GetTask(){std::string r = std::to_string(data1_);r += oper_;r += std::to_string(data2_);r += "=?";return r;}~Task(){}private:int data1_;int data2_;char oper_;int result_;int exitcode_;
};
(2)线程池
#pragma once
#include <iostream>
#include<vector>
#include<string>
#include<pthread.h>
#include<queue>
struct ThreadInfo
{pthread_t tid;std::string name;
};
static const int deafultnum=5; //默认多少个线程
template <class T>
class ThreadPool
{
public:void Lock(){pthread_mutex_lock(&mutex_);}void Unlock(){pthread_mutex_unlock(&mutex_);}void Wakeup()//线程唤醒{pthread_cond_signal(&cond_);}void ThreadSleep() //线程休眠{pthread_cond_wait(&cond_, &mutex_);}bool IsQueueEmpty(){return tasks_.empty();}std::string GetThreadName(pthread_t tid){for (const auto &ti : threads_){if (ti.tid == tid)return ti.name;}return "None";}
public:ThreadPool(int num=deafultnum):threads_(num){pthread_mutex_init(&mutex_,nullptr);pthread_cond_init(&cond_,nullptr);}static void *HandleTask(void *args) //所有线程启动后,就会去检测有没有任务,有任务就执行,没任务就休眠{ThreadPool<T> *tp=static_cast<ThreadPool<T>*>(args);std::string name=tp->GetThreadName(pthread_self());while (true){tp->Lock();while(tp->IsQueueEmpty()){tp->ThreadSleep();}T t=tp->pop();tp->Unlock();//当你拿到这个任务,这个任务就是属于你,你不需要在加锁,解锁之间。t();std::cout<<name<<"run,"<<"result:"<<t.GetResult()<<std::endl;}}void start(){int num=threads_.size();for(int i=0;i<num;i++){threads_[i].name="thread-"+std::to_string(i+1);pthread_create(&(threads_[i].tid),nullptr,HandleTask,this);}}T pop(){T t=tasks_.front();tasks_.pop();return t;}void push(const T &t)//往线程池中放任务之后线程才能执行任务{Lock();tasks_.push(t); //有任务,线程别睡了Wakeup();Unlock();}~ThreadPool(){pthread_mutex_destroy(&mutex_);pthread_cond_destroy(&cond_);}
private:std::vector<ThreadInfo> threads_; //这是个vector容器,表示有多少个线程std::queue<T> tasks_;pthread_mutex_t mutex_;pthread_cond_t cond_;
};
(3)主函数
#include <iostream>
#include "ThreadPool.hpp"
#include "Task.hpp"
#include <unistd.h>
int main()
{ThreadPool<Task> *tp=new ThreadPool<Task>(5);tp->start();srand(time(nullptr) ^ getpid());while(true){//1.构建任务int x = rand() % 10 + 1;usleep(10);int y = rand() % 5;char op = opers[rand()%opers.size()];Task t(x, y, op);tp->push(t);//ThreadPool<Task>::GetInstance()->Push(t);//2.交给线程池处理std::cout << "main thread make task: " << t.GetTask() << std::endl;sleep(1);}
}
(4)执行结果
相关文章:

线程池的实现与应用
一、线程池 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,…...

基于Java Springboot单位考勤系统
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...

近源渗透|HID ATTACK从0到1
前言 对于“近源渗透”这一术语,相信大家已经不再感到陌生。它涉及通过伪装、社会工程学等手段,实地侵入企业办公区域,利用内部潜在的攻击面——例如Wi-Fi网络、RFID门禁、暴露的有线网口、USB接口等——获取关键信息,并以隐蔽的…...
【linux】插入新硬盘如何配置:格式化、分区、自动挂载(Ubuntu)
文章目录 具体方法GPT分区表(GUID Partition Table)(建议都用这种分区方法)MBR分区表方法(最大支持2TB分区)(Master Boot Record) 附加:如何查看硬盘的型号另外ÿ…...
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-block.py
block.py ultralytics\nn\modules\block.py 目录 block.py 1.所需的库和模块 2.class DFL(nn.Module): 3.class Proto(nn.Module): 4.class HGStem(nn.Module): 5.class HGBlock(nn.Module): 6.class SPP(nn.Module): 7.class SPPF(nn.Module): 8.class C1(nn.M…...
代码随想录算法训练营第五十三天|Day53 图论
字符串接龙 https://www.programmercarl.com/kamacoder/0110.%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8E%A5%E9%BE%99.html 思路 #include <stdio.h> #include <stdlib.h> #include <string.h>#define MAX 1000 // 假设最大字符串数 #define WORD_LENGTH 100 // 假…...

LeetCode:203.移除链表元素
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:203.移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.…...

知识见闻 - 数学: 均方根 Root Mean Square
What is Root Mean Square (RMS)? 在统计学上,均方根(RMS)是均方的平方根,而均方是一组数值的平方的算术平均数。均方根也称为二次均值,是指数为 2 的广义均值的一种特例。均方根也被定义为基于一个周期内瞬时值的平方…...

机器硬件调优
grub参数 ipv6.disable1 ipv6.autoconf0 intel_pstatedisable nohzoff idlepoll intel_idle.max_cstate0 processor.max_cstate0 mceignore_ce nmi_watchdog0 transparent_hugepagenever pcie_aspm.policyperformance audit0 irqaffinity0 nosoftlockup grub2-mkconfig -o /bo…...

如何更改手机GPS定位
你是否曾想过更改手机GPS位置以保护隐私、玩游戏或访问受地理限制的内容?接下来我将向你展示如何使用 MagFone Location Changer 更改手机GPS 位置!无论是在玩Pokmon GO游戏、发布社媒贴子,这种方法都快速、简单且有效。 第一步:下…...

HarmonyOS(57) UI性能优化
性能优化是APP开发绕不过的话题,那么在HarmonyOS开发过程中怎么进行性能优化呢?今天就来总结下相关知识点。 UI性能优化 1、避免在组件的生命周期内执行高耗时操作2、合理使用ResourceManager3、优先使用Builder方法代替自定义组件4、参考资料 1、避免在…...

Mysql的加锁情况详解
最近在复习mysql的知识点,像索引、优化、主从复制这些很容易就激活了脑海里尘封的知识,但是在mysql锁的这一块真的是忘的一干二净,一点映像都没有,感觉也有点太难理解了,但是还是想把这块给啃下来,于是想通…...
hive3.1.2编译spark3安装包
此安装包是《去破解站长》在公司真实生产环境所使用的安装包。 引言:Hive引擎包括:默认MR、tez、sparkDownload:www.qupojie.com 1、Hive on Spark 1、Hive onSpark:Hive既作为存储元数据又负责SQL的解析优化,语法是HQL语法&…...

网络安全,文明上网(1)享科技,提素养
前言 在这个信息化飞速发展的时代,科技的快速进步极大地丰富了我们的生活,并为我们提供了无限的可能性。然而,随着网络世界的不断扩张,增强我们的网络素养成为了一个迫切需要解决的问题。 与科技同行,培育网络素养 技术…...
ESP32 烧录问题
ESP32 烧录问题 1.无法连接 Connecting......................................A fatal error occurred: Failed to connect to ESP32: No serial data received.这个表示通过串口连接esp32失败,可能存在多种原因,比如串口选择错误。 所选串口不是连接…...

CnosDB 实时流式计算:优化时序数据处理与降采样解决方案
在处理时序数据时,数据写入周期通常与数据采集设备的频率相关,有时每秒钟就需要处理大量的数据点。长时间处理如此多的数据会导致存储问题。一个有效的解决方案是使用流式计算,将原始数据进行降采样。 流式计算在时序数据库中指对实时数据流…...

ApiChain 从迭代测试用例到项目回归测试 核心使用教程
项目地址:ApiChain 项目主页 环境变量 环境变量是在特定的开发环境(开发、测试、uat等)下,保存的一份数据集,环境变量是发送网络请求或者执行单测的一个重要数据源。环境变量根据作用范围可以分为全局环境变量、项目…...

数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall
数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 贵在坚持! 数据样例项目地址: * 相关项目 1)数据集可视化项…...
django从入门到实战(四)——模型与数据库
1. 模型的定义与数据迁移 1.1 模型的定义 在 Django 中,模型是一个 Python 类,用于定义数据库中的数据结构。每个模型类对应数据库中的一张表,类的属性对应表中的字段。 示例: from django.db import modelsclass Blog(models…...

LeetCode:1008. 前序遍历构造二叉搜索树
目录 题目描述: 代码: 第一种: 第二种: 第三种:分治法 题目描述: 给定一个整数数组,它表示BST(即 二叉搜索树 )的 先序遍历 ,构造树并返回其根。 保证 对于给定的测试用例,总是有可能找到具有给定需求的二叉搜索树。 二叉搜索树 是一棵…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...