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 今天我们通过判断字符是否唯一这个题来了解位运算…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...

