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 今天我们通过判断字符是否唯一这个题来了解位运算…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...