linux线程池
线程池: * 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
线程池的应用场景:
* 1. 需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技 术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个 Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
* 2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
* 3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情 况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限, 出现错误.
线程池的种类:
* 线程池示例:
* 1. 创建固定数量线程池,循环从任务队列中获取任务对象,
* 2. 获取到任务对象后,执行任务对象中的任务接口
代码的大概整体结构:
main.cc
#include "threadpool.hpp"
#include "task.hpp"int main(){threadpool<task>* tp=new threadpool<task>();//在使用模板类时,始终需要提供具体的类型参数,这样编译器才能正确生成类型安全的代码。如果不加类型参数,将导致编译错误。tp->init();tp->start();int cnt=10;while(cnt){//向线程池推任务sleep(1);task t(1,1);tp->equeue(t);sleep(1);cout<<"cnt: "<<cnt--<<endl;}tp->stop();cout<<"stop!!!!!!!"<<endl;sleep(10);return 0;
}
task.hpp
#pragma once
#include<iostream>
#include<functional>
using namespace std;class task
{
public:task() {}task(int x, int y) : _x(x), _y(y){}void excute(){_result = _x + _y;}void operator()(){excute();}string debug(){string msg = to_string(_x) + "+" + to_string(_y) + "=?";return msg;}string result(){string msg = to_string(_x) + "+" + to_string(_y) +"="+ to_string(_result);return msg;}~task(){}private:int _x;int _y;int _result;
};
thread.hpp
#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
#include <functional> //回调方法using namespace std;
namespace threadmodel // 构造一个命名空间
{//typedef void (*func_t)(threaddate *td);// typedef void (*func_t)(const string &name); // func_t 是一个指向返回类型为 void 且有参数的函数的指针。// // func_t 现在可以用作一个函数指针类型的别名,表示任何指向带字符串参数且返回类型为 void 的函数的指针。using func_t=function<void(const string&)>;//返回值为void,参数为空的函数类型class thread{public:void excute(){cout << _name << " is running ! " << endl;_running = true;_func(_name); // 回调不仅回调运行,他还得结束_running = false; // 回调完就结束了}public:thread(const string &name, func_t func) : _name(name), _func(func){cout << "create: " << name << " done! " << endl;}static void *threadroutine(void *agv) // 只要线程启动,新线程都会启动这个方法{ // 因为是类内定义的方法,所以会隐含一个this指针参数,加了static就可以,这是因为 static 成员函数不与类的实例相关联,因此它不需要 this 指针。thread *self = static_cast<thread *>(agv); // 获得当前对象。因为要调用_func,但_func是动态的,静态函数无法访问所以传this指针访问self->excute();return nullptr;}bool start(){ // 线程启动方法int n = ::pthread_create(&_tid, nullptr, threadroutine, this);// 使用::pthread_create确保调用的是全局命名空间中的pthread_create函数,避免当前命名空间内可能存在的同名函数的影响。// 直接使用 pthread_create 会根据当前命名空间查找,如果找到了同名函数,就会调用那个函数。if (n != 0)return false;return true;}string status(){if (_running){return "running";}elsereturn "sleep";}void stop(){ // 线程停止方法if (_running){ // 得先有线程才能停止_running = false; // 状态停止::pthread_cancel(_tid);cout << _name << " stop ! " << endl;}}void join(){ // 线程等待方法if (!_running){ // 没有running才值得join::pthread_join(_tid, nullptr);cout << _name << " join ! " << endl;}}string threadname(){return _name;}~thread(){}private:string _name; // 线程的名字pthread_t _tid; // 线程的idbool _running; // 是否处于工作状态func_t _func; // 线程要执行的回调函数};
};
threadpool.hpp
#pragma once
#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>
#include <queue>
#include <functional>
#include "thread.hpp"using namespace std;
using namespace threadmodel;static const int faultnum = 5;void test()
{while (true){cout << "hello world" << endl;sleep(1);}
}template <typename T>
class threadpool
{
private:void lockqueue(){pthread_mutex_lock(&_mutex);}void unlockqueue(){pthread_mutex_unlock(&_mutex);}void wakeup(){pthread_cond_signal(&_cond); // 唤醒一个}void wakeupall(){pthread_cond_broadcast(&_cond); // 唤醒全部}void Sleep(){pthread_cond_wait(&_cond, &_mutex); // 等待}bool isempty(){return _task_queue.empty();}void handlertask(const string &name){ // 每个线程都执行这个方法while (true){// 拿任务lockqueue();while (isempty() && _isrunning) // 没任务并且线程不退出{ // 防止伪唤醒·用while// 为空的任务列表,那就去休眠_sleep_thread_num++;Sleep();_sleep_thread_num--;}// 判定一种情况if (isempty() && !_isrunning){ // 任务队列空的并且线程池想退出cout << name << ": " << " quit" << endl ;unlockqueue();break;}// 有任务T t = _task_queue.front(); // 取任务_task_queue.pop(); // 老任务弹走unlockqueue();t(); // 处理任务,此处不用/不能在临界区中处理,避免浪费时间因为任务已经是你的了,你自己去处理,不占用公共资源cout << name << ": " << t.result() << endl;}}public:threadpool(int thread_num = faultnum) : _thread_num(thread_num), _isrunning(false), _sleep_thread_num(0){pthread_mutex_init(&_mutex, nullptr);pthread_cond_init(&_cond, nullptr);}void init(){ // 初始化func_t func = bind(&threadpool::handlertask, this, placeholders::_1);for (int i = 0; i < _thread_num; i++){string threadname = "thread-" + to_string(i + 1);_threads.emplace_back(threadname, func); // 提供名字和任务// emplace_back它的作用是在容器的末尾直接构造一个对象。emplace_back允许你直接传递构造对象所需的参数}}void start(){ // 开始_isrunning = true;for (auto &threadd : _threads){threadd.start();}}void equeue(const T &in){ // 向线程池中推送任务lockqueue(); // 加if (_isrunning)//运行才可以{_task_queue.push(in);if (_sleep_thread_num > 0)wakeup(); // 唤醒}unlockqueue(); // 解}void stop(){lockqueue();_isrunning = false;wakeupall();unlockqueue();}~threadpool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);}private:int _thread_num; // 期待有多少线程vector<thread> _threads; // 对象全在这里queue<T> _task_queue; // 任务队列,他就是临界资源bool _isrunning; // 是否运行int _sleep_thread_num; // 休眠的线程的个数pthread_mutex_t _mutex; // 对queue的锁pthread_cond_t _cond; // 条件变量
};
日志:软件运行的记录信息,向显示器打印,向文件打印,特定的格式(统一格式输出) ;
格式:[日志等级][pid][filename][filenumber][time] 日志内容(支持可变参数);
日志等级:
1. DEBUG
//详细的信息,用于调试程序。包括内部状态和控制流的信息。通常在开发和测试阶段使用。
2. INFO
//一般信息,表示程序正常运行时的重要事件。例如系统启动、关闭或者某个操作成功完成等。
3. WARNING
//警告信息,表示可能会导致问题的事件。并不意味着错误,但可能需要注意的情况,例如某个功能即将过时。
4. ERROR
//错误信息,表示程序中发生了问题。这些问题会影响某个特定的功能或操作,但不会导致程序崩溃。
5. FATAL --致命的
//致命错误,表示程序遇到严重问题并即将停止运行。例如,关键资源不可用,无法继续执行。
相关文章:
linux线程池
线程池: * 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用࿰…...
PyTorch图像分类实战——基于ResNet18的RAF-DB情感识别(附完整代码和结果图)
PyTorch图像分类实战——基于ResNet18的RAF-DB情感识别(附完整代码和结果图) 关于作者 作者:小白熊 作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测…...
【OccNeRF: Advancing 3D Occupancy Prediction in LiDAR-Free Environments】阅读笔记
【OccNeRF: Advancing 3D Occupancy Prediction in LiDAR-Free Environments】阅读笔记 1. 论文概述Abstract1. Introduction2. Related work2.1 3D Occupancy Prediction2.2 Neural Radiance Fields2.3 Self-supervised Depth Estimation 3. Method3.1 Parameterized Occupanc…...
DDRPHY数字IC后端设计实现系列专题之后端设计导入,IO Ring设计
本章详细分析和论述了 LPDDR3 物理层接口模块的布图和布局规划的设计和实 现过程,包括设计环境的建立,布图规划包括模块尺寸的确定,IO 单元、宏单元以及 特殊单元的摆放。由于布图规划中的电源规划环节较为重要, 影响芯片的布线资…...
EDA --软件开发之路
之前一直在一家做数据处理的公司,从事c开发,公司业务稳定,项目有忙有闲,时而看下c,数据库,linux相关书籍,后面跳槽到了家eda公司,开始了一段eda开发之路。 eda 是 electric design …...
51c~目标检测~合集2
我自己的原文哦~ https://blog.51cto.com/whaosoft/12377509 一、总结 这里概述了基于深度学习的目标检测器的最新发展。同时,还提供了目标检测任务的基准数据集和评估指标的简要概述,以及在识别任务中使用的一些高性能基础架构,其还涵盖了…...
计算机低能儿从0刷leetcode | 33.搜索旋转排列数组
题目:33. 搜索旋转排序数组 思路:看到时间复杂度要求是O(log N)很容易想到二分查找,普通的二分查找我们已经掌握,本题中的数组可以看作由两个分别升序的数组拼成,在完全升序的部分中进行二分查找是容易的,…...
SpringBoot+VUE2完成WebSocket聊天(数据入库)
下载依赖 <!-- websocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- MybatisPlus --><dependency><groupId>com.ba…...
理解 CSS 中的绝对定位与 Flex 布局混用
理解 CSS 中的绝对定位与 Flex 布局混用 在现代网页设计中,CSS 布局技术如 flex 和绝对定位被广泛使用。然而,这两者结合使用时,可能会导致一些意想不到的布局问题。本文将探讨如何正确使用绝对定位元素,避免它们受到 flex 布局的…...
Redis 事务 问题
前言 相关系列 《Redis & 目录》《Redis & 事务 & 源码》《Redis & 事务 & 总结》《Redis & 事务 & 问题》 参考文献 《Redis事务详解》 Redis事务是什么? 标准的事务是指执行时具备原子性/一致性/隔离性/持久性的一系列操作。…...
Cpp学习手册-进阶学习
C标准库和C20新特性 C标准库概览: 核心库组件介绍: 容器: C 标准库提供了多种容器,它们各有特点,适用于不同的应用场景。 std::vector: vector:动态数组,支持快速随机访问。 #in…...
代码随想录-字符串-反转字符串中的单词
题目 题解 法一:纯粹为了做出本题,暴力解 没有技巧全是感情 class Solution {public String reverseWords(String s) {//首先去除首尾空格s s.trim();String[] strs s.split("\\s");StringBuilder sb new StringBuilder();//定义一个公共的字符反转…...
勒索软件通过易受攻击的 CyberPanel 实例攻击网络托管服务器
一个威胁行为者(或可能多个)使用 PSAUX 和其他勒索软件攻击了大约 22,000 个易受攻击的 CyberPanel 实例以及运行该实例的服务器上的加密文件。 PSAUX 赎金记录(来源:LeakIX) CyberPanel 漏洞 CyberPane…...
Open WebUI + openai API / vllm API ,实战部署教程
介绍Open WebUI + Ollama 的使用: https://www.dong-blog.fun/post/1796 介绍vllm 的使用:https://www.dong-blog.fun/post/1781 介绍 Ollama 的使用: https://www.dong-blog.fun/post/1797 本篇博客玩个花的,Open WebUI 本身可以兼容openai 的api, 那来尝试一下。 仅供…...
InsuranceclaimsController
目录 1、 InsuranceclaimsController 1.1、 保险理赔结算 1.2、 生成预约单号 1.3、 保存索赔表 InsuranceclaimsController using QXQPS.Models; using QXQPS.Vo; using System; using System.Collections; using System.Collections.Generic; using System.Li…...
如何成为开源代码库Dify的contributor:解决issue并提交PR
前言 Dify 是一个开源的大语言模型(LLM)应用开发平台,它融合了后端即服务(Backend as Service)和LLMOps的理念,旨在简化和加速生成式AI应用的创建和部署。Dify提供了一个用户友好的界面和一系列强大的工具…...
SQL进阶技巧:巧用异或运算解决经典换座位问题
目录 0 问题描述 1 数据准备 2 问题分析 2.1 什么是异或 2.2异或有什么特性? 2.3 异或应用 2.4 本问题采用异或SQL解决方案 3 小结 0 问题描述 表 seat中有2个字段id和student id 是该表的主键(唯一值)列,student表示学生姓名。 该表的每一行都表示学生的姓名和 ID。…...
【MySQL】 运维篇—数据库监控:使用MySQL内置工具(如SHOW命令、INFORMATION_SCHEMA)进行监控
随着应用程序的增长,数据库的性能和稳定性变得至关重要。监控数据库的状态和性能可以帮助数据库管理员(DBA)及时发现问题,进行故障排查,并优化数据库的运行效率。通过监控工具,DBA可以获取实时的性能指标、…...
【温酒笔记】DMA
参考文档:野火STM32F103 1. Direct Memory Access-直接内存访问 DMA控制器独立于内核 是一个单独的外设 DMA1有7个通道DMA2有5个通道DMA有四个等级,非常高,高,中,低四个优先级如果优先等级相同,通道编号越…...
力扣判断字符是否唯一(位运算)
文章目录 给一个数n,判断它的二进制位中第x位是0还是1(从0开始计数)将一个数n的二进制位第X位修改为1(从0开始计数)将一个数n的二进制第x位修改为0(从0开始计数)提取一个数n二进制中最右侧的1去掉一个数n二进制表示中最右侧的1 今天我们通过判断字符是否唯一这个题来了解位运算…...
GPU和CPU区别?为什么挖矿、大模型都用GPU?
GPU(图形处理单元)和CPU(中央处理单元)是计算机中两种不同类型的处理器,它们在设计和功能上有很大的区别。 CPU是计算机的大脑,专门用于执行各种通用任务,如操作系统管理、数据处理、多任务处理等。它的架构设计旨在适应多种任务,…...
新兴斗篷cloak技术,你了解吗?
随着互联网技术的飞速发展,网络营销领域也经历了翻天覆地的变革。 从最早的网络横幅广告到如今主流的搜索引擎和社交媒体营销,广告形式变得越来越多样。 其中,搜索引擎广告一直以其精准投放而备受青睐,但近年来,一项名…...
【抽代复习笔记】34-群(二十八):不变子群的几道例题
例1:证明,交换群的任何子群都是不变子群。 证:设(G,o)是交换群,H≤G, 对任意的a∈G,显然都有aH {a o h|h∈H} {h o a|h∈H} Ha。 所以H⊿G。 【注:规范的不变子群符号是一个顶角指向左边…...
Chrome和Firefox如何保护用户的浏览数据
在当今数字化时代,保护用户的浏览数据变得尤为重要。浏览器作为我们日常上网的主要工具,其安全性直接关系到个人信息的保密性。本文将详细介绍Chrome和Firefox这两款主流浏览器如何通过一系列功能来保护用户的浏览数据。(本文由https://chrom…...
CentOS 7镜像下载
新版本系统镜像下载(当前最新是CentOS 7.4版本) CentOS官网 官网地址 http://isoredirect.centos.org/centos/7.4.1708/isos/x86_64/ http://mirror.centos.org/centos/7/isos/ 国内的华为云,超级快:https://mirrors.huaweiclou…...
opencv-windows-cmake-Mingw-w64,编译opencv源码
Windows_MinGW_64_OpenCV在线编译动态库,并使用在C项目: (mingw-w64 cmakegithub actions方案) 修改版opencv在线编译: 加入opencv-contrib库, 一起编译生成动态库,在线编译好的opencv动态库,可以下载使用.验证opencv动态库是否可用的模板项目,测试opencv动态库是否可用的模板…...
Puppeteer点击系统:解锁百度流量点击率提升的解决案例
在数字营销领域,流量和搜索引擎优化(SEO)是提升网站可见性的关键。我开发了一个基于Puppeteer的点击系统,旨在自动化地提升百度流量点击率。本文将介绍这个系统如何通过模拟真实用户行为,优化关键词排名,并…...
Kyber原理解析
Kyber是一种IND-CCA2安全的密钥封装机制。Kyber的安全性基于在模格(MLWE问题)中解决LWE问题的难度。Kyber的构造采⽤两阶段⽅法:⾸先介绍⼀种⽤来加密固定32字节⻓度的消息原⽂的IND-CPA安全性的公钥加密⽅案,我们称之为 CPAPKE&a…...
2024 CCF CSP-J/S 2024 第二轮认证 真题试卷
2024年信息学奥赛CSP-J2入门级复赛真题试卷 题目总数:4 总分数:400 编程题 第 1 题 问答题 扑克牌(poker) 【题目描述】 小 P 从同学小 Q 那儿借来一副 n 张牌的扑克牌。 本题中我们不考虑大小王,此时每张牌具有两个属性:花色和…...
Android 无障碍服务常见问题梳理
android 无障碍服务本意是为了帮助盲人操作手机而设计,但是现在也有人利用这个做自动化操作。 本片文章讲述的主要用作自动化方面。 官方文档 关于配置方法和接口列表,参考 无障碍 比较常用的接口: 1. 执行点击操作 2. 触摸屏幕…...
织梦网站修改/网站优化工具
Hibernate的一级缓存什么是缓存1 数据存到数据库里面,数据库本身是文件系统,Java中使用流方式操作文件效率不是很高。(1)把数据存到内存里面,不需要使用流方式,可以直接读取内存中数据(2&#x…...
在电脑上打不开政府网站/网络推广公司
请问如何在一个List最开始插入一个元素,其他元素一次向后移动一位? [问题点数:20分] 不显示删除回复 显示所有回复 显示星级回复 显示得分回复 只显示楼主 收藏msn365msn365 结帖率&…...
网页制作创建站点/百度一下百度下载
基数排序算法是一种排序的算法。简而言之,先对所有数的个位进行排序、接着对十位进行排序,然后百位进行排序,以此类推,直到所有的位数排完,得到最终的排序。具体的步骤:生成10个队列(0-9&#x…...
陕西专业网站开发联系电话/上海网站建设开发公司
大多数人注意到元素是行列有序的,会马上想到对每行(或列)进行二分查找,每行(或列)需要logN时间,N行(或列)共需要NlogN时间,很容易写出如下代码1234567891011121314151617181920//注意…...
b2c网站seo优化怎么做/网络营销的概述
NFS是Network File System的缩写,即网络文件系统,这里不再详细讲解NFS的配置,具体配置看这篇博客CentOS 6 nfs共享存储配置。这里重点说的是在服务器端共享多个文件夹。 1、配置/etc/exports文件 假设服务器端要共享的目录是/var/shared/fold…...
兰州网站怎么建设/兰蔻搜索引擎营销案例
假如有一个包含产品目录的数据库表,其中每种类别的物品占一行。对于每种物品要存储的信息包含产品描述和价格,以及生产该产品的供应商信息。 现在,假如有由同一供应商生产的多种物品,那么在何处存储供应商信息(如供应…...