当前位置: 首页 > news >正文

线程池的封装(c/c++)

        前言:本文将要封装的线程池相关接口是基于之前一篇文章中的实现(文章链接:Linux多线程编程的艺术:封装线程、锁、条件变量和信号量的工程实践-CSDN博客)。不过无需担心,即使您没有阅读过前文,只要具备线程、互斥锁和条件变量等基础知识,完全可以理解本文内容。

目录

一、理解线程池

二、框架设计

三、成员函数实现

四、单例模式设计

五、测试

六、源码


一、理解线程池

池化技术

        所谓“池化技术”,就是程序先向系统申请过量的资源,然后⾃⼰管理,以备不时之需。之所以要申请过量的资源,是因为每次申请该资源都有较⼤的开销,不如提前申请好了,这样使⽤时就会变得⾮常快捷,⼤⼤提⾼程序运⾏效率。

线程池的意义:

  • 降低资源消耗:复用已创建的线程,减少线程创建销毁的开销。

  • 提高响应速度:任务到达时可以直接执行,无需等待线程创建。

  • 提高线程可管理性:统一分配、调优和监控线程。

二、框架设计

        线程池本质就是一个类,它管理了批量的线程和任务,如何管理?先描述,再组织。我们使用数组来存储线程,队列来存储任务(任务本质就是函数,lambda,或仿函数等)。

其次线程之间需要保持互斥,线程和任务队列需要保持同步,所以还需要锁,条件变量。

核心成员变量:

  • 数组:用来存储线程。
  • 队列:用来存储任务。
  • 条件变量

核心成员函数

  • HandlerTask:从队列中获取并执行任务,让单个线程执行。
  • ThreadPool:构造函数,用于创建批量线程,并将HandlerTask函数交给线程。
  • Push:外部给线程池派发任务(即入队)。
  • Join:线程等待。

如下:

#define NUM 5 // 线程个数
namespace my_threadpool
{template <typename T> //任务类型class ThreadPool{public:ThreadPool(int num = NUM) {}void HandlerTask()bool Push(const T &task);void Join();private:vector<thread<T>> _threads;queue<T> _taskq;Mutex _lock;Cond _cond;};
}

当然这些只是核心成员,在后面实现这些函数时还会延伸出更多的成员变量和成员函数。 

线程池相当于生产者消费者模型中的交易场所和消费者这一部分,关于生产者消费者模型:

多线程编程实战:基于阻塞队列与环形队列的生产者消费者模型详解_环形数组 生产者消费者-CSDN博客

三、成员函数实现

构造函数 ThreadPool(int num = NUM)

循环创建num个线程,用lambda包装HandlerTask()作为线程函数,然后push到数组中。

ThreadPool(int num = NUM)
{for (int i = 0; i < num; i++){_threads.emplace_back([this](){HandlerTask();});}
}

这里也可以不使用lambda表达式。 

void HandlerTask()

        为了代码的健壮性,我们添加一个参数(成员变量_isruning)用来标记线程池是否正在运行,初始化为false,在程序执行到HandlerTask后设为true。这个参数用来防止用户对已经回收的线程池进行任务派发或线程回收。

        HandlerTask是单个线程在执行,线程要通过这个函数获取并执行任务,这个逻辑需要重复执行,所以做一个死循环。接下来到队列中取任务,队列是临界资源需要加锁,这里使用RAII模式。其次为了和队列保持同步,当队列为空时需要进行等待。如下:

void HandlerTask()
{_isrunning = true;while (true){T tk;LockGuard lock(_lock);{while (_taskq.empty()){_cond.Wait(_lock);}tk = _taskq.front();_taskq.pop();}tk(); }
}

        注意:必须选择循环等待,因为可能会有这样的情况:只派发了一个任务但多个线程一起被唤醒,进行循环判断可以解决。

这里HandlerTask函数实现不是最终形态,在后文会根据需求进行改进。

Push实现

        向任务队列推送任务,要保证_isrunning为true,其次访问临界资源要加锁,然后向队列里push任务。因为队列有任务了,接下来需要将线程唤醒,这里我们还是优雅一点,不要粗鲁地直接把线程都唤醒。

        添加变量_sleepnum来记录等待的线程个数,如果所有线程都在等待再进行唤醒,并且只唤醒一个就行。

_sleepnum在HandlerTask函数中进行维护,即:

while (_taskq.empty())
{_sleepnum++;_cond.Wait(_lock);_sleepnum--;
}

封装一个函数用来唤醒一个线程,如下: 

void WakeOnceThread()
{_cond.Signal();
}

 Push实现如下:

bool Push(const T &task)
{if (_isrunning){LockGuard lock(_lock);{_taskq.push(task);if (_sleepnum == _threads.size())WakeOnceThread();// 唤醒一个线程}return true;}return false;
}

Join实现

线程池的回收,遍历每个线程的join就行,在此之前要满足两个条件:

  1. 线程池_isrunning为true。
  2. 保证任务队列里的任务已经做完了,然后让线程执行的函数退出。

对第1点直接用if判断就能解决。

针对第2点,我们可以封装一个Stop函数用来等任务做完后,让线程函数退出。

Stop的实现

        Stop函数的主要目的是让线程函数(HandlerTask)退出,所以就需要把全部线程唤醒,让它们往下执行,当然这还不够,我们要让它退出循环判断队空的逻辑,这个时候_isrunning就派上大用处了,把_Stop函数中把isrunning设为false。在HandlerTask函数中如果_isrunning为false则退出函数,当然还要保证把队列任务做完,具体实现如下:

void Stop()
{_isrunning = false;WakeAllThread();cout << "所有线程被唤醒" << endl;
}
void HandlerTask()
{_isrunning = true;while (true){T tk;LockGuard lock(_lock);{while (_taskq.empty() && _isrunning){_sleepnum++;_cond.Wait(_lock);_sleepnum--;}if (!_taskq.empty()){tk = _taskq.front();_taskq.pop();}else break;}tk(); }
}

Join实现如下:

void Join()
{if (!_isrunning) return;Stop();for (auto &thread : _threads){thread.Join();cout << "线程" << thread.getname() << "等待成功" << endl;}
}

        Stop,WakeOneThread,WakeAllThread,HandlerTask这些函数都是为实现主函数而延伸的,将这些函数设为私有更为适宜,不要暴露给用户。  

四、单例模式设计

对于线程池我们希望它只能创建一份,即单例模式。

        单例模式:一个类只能实例化出一个对象,类似⼀个男⼈只能有⼀个媳妇。  单例模式的实现有两种方法:                     

  • 饿汉模式:吃完饭, ⽴刻洗碗, 这种就是饿汉⽅式. 因为下⼀顿吃的时候可以⽴刻拿着碗就能吃饭。
  • 懒汉模式:吃完饭, 先把碗放下, 然后下⼀顿饭⽤到这个碗了再洗碗, 就是懒汉⽅式。

        饿汉模式会在程序运行后就为线程池开辟空间,创建线程池。而懒汉模式只是做简单的声明,到程序执行到需要用线程池的代码时再进行创建。

        这里我们选择使用懒汉模式,因为它延迟加载的特点,可以增加内存资源的利用率(在申请这块内存之前可以先用来存储其他数据,完成很多事情)。

单例模式需要注意的事项:

  • 把构造函数设为私有,不让它默认生成拷贝构造函数,拷贝赋值函数。
  • 定义全局的静态指针变量(这是针对懒汉模式,饿汉模式直接定义对象实体)。
  • 需要定义一个获取单例对象的方法。

在类成员变量中声明:

  • static ThreadPool<T> *_pthreadpool;

在类外,命名空间中定义:

  • template <typename T>
  • ThreadPool<T>* ThreadPool<T>::_pthreadpool = nullptr;

接下来是封装一个获取对象的函数。这个函数有很多细节需要注意:

        如果对象已经创建(指针不为空)直接返回,如果不是则进行创建对象,注意这里需要加锁,因为可能有多个线程使用线程池(生产者消费者模型),它们同时执行该函数。加锁后还需要判断指针是否为空,因为加锁只保证了不同时创建,其他线程拿到锁后可能会再次创建。

        注意这里的锁是拿给外部线程用的,而不是拿给线程池用的锁,所以同样地把这个锁定义成静态全局变量,如:

在类成员变量中声明:

  • static Mutex _lock2;

在类外,命名空间中定义:

  • template <typename T>
  • Mutex ThreadPool<T>::_lock2;
static ThreadPool<T> *GetTreadPool()
{if (_pthreadpool == nullptr){LockGuard lock(_lock2);if (_pthreadpool == nullptr){_pthreadpool = new ThreadPool<T>();cout << "ThreadPool创建" << endl;}}return _pthreadpool;
}

        最后有一点,在调用GetTreadPool成员函数之前是没有对象的,所以不能通过对象来访问,这里就将它设为静态成员函数

五、测试

测试代码:

using task_t = std::function<void()>;
void Download()
{cout << "我是一个下载任务..." <<endl;
}
int main()
{int count=5;while(count--){ThreadPool<task_t>::GetTreadPool()->Push(Download);sleep(1);}ThreadPool<task_t>::GetTreadPool()->Join();return 0;
}

测试结果: 

六、源码

ThreadPool.hpp

#pragma once
#include <iostream>
#include <pthread.h>
#include <queue>
#include <vector>
#include "Cond.hpp"
#include "Mutex.hpp"
#include "Thread.hpp"
using namespace std;
using namespace my_cond;
using namespace my_mutex;
using namespace my_thread;
#define NUM 5
namespace my_threadpool
{template <typename T>class ThreadPool{private:ThreadPool(const ThreadPool<T> &) = delete;ThreadPool<T> &operator=(const ThreadPool<T> &) = delete;ThreadPool(int num = NUM): _sleepnum(0), _isrunning(false){for (int i = 0; i < num; i++){_threads.emplace_back([this](){HandlerTask();});}}void WakeAllThread(){LockGuard lock(_lock);_cond.Broadcast();}void WakeOnceThread(){_cond.Signal();}void HandlerTask(){_isrunning = true;while (true){T tk;LockGuard lock(_lock);{while (_taskq.empty() && _isrunning){_sleepnum++;_cond.Wait(_lock);_sleepnum--;}if (!_taskq.empty()){tk = _taskq.front();_taskq.pop();}elsebreak;}tk();}}void Stop(){_isrunning = false;WakeAllThread();cout << "所有线程被唤醒" << endl;}~ThreadPool(){}public:static ThreadPool<T> *GetTreadPool(){if (_pthreadpool == nullptr){LockGuard lock(_lock2);if (_pthreadpool == nullptr){cout << "ThreadPool创建" << endl;_pthreadpool = new ThreadPool<T>();}}return _pthreadpool;}bool Push(const T &task){if (_isrunning){LockGuard lock(_lock);{_taskq.push(task);if (_sleepnum == _threads.size())WakeOnceThread(); // 唤醒一个线程}return true;}return false;}void Join(){if (!_isrunning)return;Stop();for (auto &thread : _threads){thread.Join();cout << "线程" << thread.getname() << "等待成功" << endl;}}private:vector<thread> _threads;queue<T> _taskq;Mutex _lock;Cond _cond;int _sleepnum;bool _isrunning;static ThreadPool<T> *_pthreadpool;static Mutex _lock2;};template <typename T>ThreadPool<T> *ThreadPool<T>::_pthreadpool = nullptr;template <typename T>Mutex ThreadPool<T>::_lock2;
}

test.cc 

#include "ThreadPool.hpp"
#include <functional>
using namespace my_threadpool;
using task_t = std::function<void()>;
void Download()
{cout << "我是一个下载任务..." <<endl;
}
int main()
{int count=5;while(count--){ThreadPool<task_t>::GetTreadPool()->Push(Download);sleep(1);}ThreadPool<task_t>::GetTreadPool()->Join();return 0;
}

需要其他头文件的小伙伴到下文自取:

Linux多线程编程的艺术:封装线程、锁、条件变量和信号量的工程实践-CSDN博客

相关文章:

线程池的封装(c/c++)

前言&#xff1a;本文将要封装的线程池相关接口是基于之前一篇文章中的实现&#xff08;文章链接&#xff1a;Linux多线程编程的艺术&#xff1a;封装线程、锁、条件变量和信号量的工程实践-CSDN博客&#xff09;。不过无需担心&#xff0c;即使您没有阅读过前文&#xff0c;只…...

「数据可视化 D3系列」入门第六章:比例尺的使用

比例尺的使用 一、比例尺是什么&#xff1f;典型示例&#xff1a; 二、常用比例尺类型1. 线性比例尺 (scaleLinear)2. 序数比例尺 (scaleOrdinal)3. 其他常用比例尺类型&#xff1a; 三、实际应用主要改进点说明 四、比例尺的高级用法1. 颜色比例尺2. 时间比例尺3. 分段比例尺 …...

巧用ChatGPT生成适合小白的Python练习题,助力编程入门

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;AI 【前言】 在Python学习的道路上&#xff0c;练习题是帮助小白快速掌握编程知识和技能的重要工具。然而&#xff0c;…...

iOS15描述文件在哪下载?iOS15测试版描述文件下载与升级教程

iOS 15正式发布&#xff1a;全面升级体验与开发者工具推荐 今天凌晨&#xff0c;备受关注的WWDC21开发者大会上如期召开&#xff0c;果粉期待已久的新一代iOS 15操作系统正式发布。iOS 15系统带来了全新FaceTime与通知界面&#xff0c;并对照片、天气、钱包、地图等应用进行了…...

Java面试(2025)—— Spring

什么是Spring? 结构化回答&#xff08;总分总模式&#xff09; ① 一句话定义 “Spring 是一个开源的 Java 企业级应用框架&#xff0c;核心目标是简化企业应用的开发&#xff0c;通过控制反转&#xff08;IoC&#xff09;、依赖注入&#xff08;DI&#xff09;和面向切面编…...

【C++ Qt】Hello World、初始信号槽、理解对象树 ~~~(通俗易懂 图文并茂)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是Qt的第二篇&#xff0c;带你认识Qt中几个简单的控件如何实现&#xff0c;以及通过信号槽的方式实现一定的用户和程序的联动&#xff0c;还有许多…...

2025.04.16【GroupedandStackedbarplot】生信数据可视化技法

Negative values This blogpost shows what happens when the dataset includes negative values. Most basic streamchart The most basic streamchart you can build with R and the streamgraph package. 文章目录 Negative valuesMost basic streamchart 2025.04.16【Gro…...

java 设计模式之代理模式

简介 代理模式&#xff1a;使用代理类来增强目标类的功能。在代码结构上&#xff0c;代理对象持有目标对象&#xff0c;通过代理对象访问目标对象&#xff0c;这样可以在不改变目标对象的前提下增加额外的功能&#xff0c;如权限校验、缓存等 代理模式内部的角色&#xff1a;…...

Spring Boot实战:基于策略模式+代理模式手写幂等性注解组件

一、为什么需要幂等性&#xff1f; 核心定义&#xff1a;在分布式系统中&#xff0c;一个操作无论执行一次还是多次&#xff0c;最终结果都保持一致。 典型场景&#xff1a; 用户重复点击提交按钮网络抖动导致的请求重试消息队列的重复消费支付系统的回调通知 不处理幂等的风…...

【.net core】【watercloud】数据库连接报错问题

错误信息&#xff1a; 中文提示 : 连接数据库过程中发生错误&#xff0c;检查服务器是否正常连接字符串是否正确&#xff0c;错误信息&#xff1a;Cannot Open when State is Connecting.DbType"MySql";ConfigId"0". English Message : Connection open …...

69. x 的平方根

目录 一、问题描述 二、解题思路 三、代码 四、复杂度分析 一、问题描述 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数…...

计算机网络基础概论

计算机网络基础概论 目录 一、网络基本概念 1.1. 网络 1.2 互联网 1.3 ip地址 1.3.1 作用 1.3.2 分类 1.4 MAC地址 1.4.1 MAC地址与 IP 地址的关系 1.5 网络协议 二、网络分层模型 2.1 物理层 2.2 数据链路层 2.3 网络层 2.4 传输层 2.5 会话层 2.6 表示层 2.7…...

京东3D空间视频生成技术探索与应用

1. 背景 近年来&#xff0c;随着社交媒体、流媒体平台以及XR设备的快速发展&#xff0c;沉浸式3D空间视频的需求迅猛增长&#xff0c;尤其是在短视频、直播和电影领域&#xff0c;正在重新定义观众的观看体验。2023年&#xff0c;苹果公司发布的空间视频技术为这一趋势注入了新…...

吉利矩阵(DFS)

所有元素为非负整数&#xff0c;且各行各列的元素和都等于 7 的 33 方阵称为 “吉利矩阵”&#xff0c;因为这样的矩阵一共有 666 种。 本题就请你统计一下&#xff0c;各行各列的元素和都等于 5 的 33 方阵一共有多少种&#xff1f; 思路&#xff1a;统计方法数&#xff0c;…...

突破反爬限制的智能数据采集实战 —— 面向中小企业的高效信息监控方案

在当前数据驱动的商业环境中&#xff0c;如何高效、稳定地获取网络数据&#xff0c;已成为众多中小企业进行市场洞察、竞品监测与品牌舆情管理的关键能力。本文将分享一个基于先进API技术构建的社交媒体热点监控系统&#xff0c;聚焦实际应用场景&#xff0c;展示如何在合规前提…...

从0到1:让AI赋能计算机的全流程实践指南

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;AI 【前言】 在数字化浪潮席卷全球的今天&#xff0c;AI&#xff08;人工智能&#xff09;早已不是科幻电影中的虚构概…...

IntelliJ IDEA 2025.1 发布 ,默认 K2 模式 | Android Studio 也将跟进

2025.1 版本已经发布&#xff0c;在此之前我们就聊过该版本的 《Terminal 又发布全新重构版本》&#xff0c;而现在 2025.1 中的 K2 模式也成为了默认选项。 可以预见&#xff0c;这个版本可能会包含不少大坑&#xff0c;为下个 Android Studio 祈祷。 首先有一点可以确定&…...

MCP、A2A、Function Calling:AI架构设计的三驾马车

随着AI浪潮的到来&#xff0c;各种技术和概念也层出不穷&#xff0c;作为技术人应该第一时间掌握其核心概念与原理&#xff0c;以便于在工作和交流中傻傻分不清楚&#xff0c;本文主要就最近大家提及比较多的MCP、A2A和Function Call做下普及与区分 在当今快速发展的AI领域&a…...

NO.96十六届蓝桥杯备战|图论基础-多源最短路|Floyd|Clear And Present Danger|灾后重建|无向图的最小环问题(C++)

多源最短路&#xff1a;即图中每对顶点间的最短路径 floyd算法本质是动态规划&#xff0c;⽤来求任意两个结点之间的最短路&#xff0c;也称插点法。通过不断在两点之间加⼊新的点&#xff0c;来更新最短路。 适⽤于任何图&#xff0c;不管有向⽆向&#xff0c;边权正负&…...

OpenHarmony - 小型系统内核(LiteOS-A)(六)

OpenHarmony - 小型系统内核&#xff08;LiteOS-A&#xff09;&#xff08;六&#xff09; 七、文件系统 支持的文件系统 FAT 基本概念 FAT文件系统是File Allocation Table&#xff08;文件配置表&#xff09;的简称&#xff0c;主要包括DBR区、FAT区、DATA区三个区域。其…...

“星睿O6” AI PC开发套件评测 - Windows on Arm 安装指南和性能测评

引言 Radxa联合此芯科技和安谋科技推出全新的"星睿O6"迷你 ITX 主板。该系统搭载了 CIX P1&#xff08;CD8180&#xff09;12 核 Armv9 处理器&#xff0c;拥有高达30T算力的NPU和高性能的GPU&#xff0c;最高配备64GB LPDDR内存&#xff0c;并提供了如 5GbE、HDMI …...

JS实现RSA加密

目录 目标 环境 实现RSA加解密 计算RSA加密允许的最大字节长度 目标 使用JS实现RSA加密解密。计算RSA加密允许的最大字节长度。 环境 node-rsa 实现RSA加解密 const NodeRSA require(node-rsa);function getKey() {const keyLength512// 创建 RSA 密钥对const key new …...

Seata方案详细

Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff09;是阿里开源的分布式事务解决方案&#xff0c;支持多种事务模式&#xff0c;提供一站式的事务管理能力。以下是其核心原理、模式及实践的详细解析&#xff1a; 一、Seata核心架构与角色 Se…...

深入了解v-model的原理:v-model拆分为value属性和input事件,表单类组件的封装并用v-model简化代码

文章目录 1.v-model的原理1.1.验证:在input文本输入框中不使用v-model实现双向数据绑定1.2.验证:v-model在下拉菜单中的拆分 2.表单类组件的封装2.1.原理或步骤2.2.示例:表单类组件封装之下拉菜单select的封装 3.使用v-model简化代码完整代码 4.拓展示例:完成input文本输入框的…...

设计模式每日硬核训练 Day 14:组合模式(Composite Pattern)完整讲解与实战应用

&#x1f504; 回顾 Day 13&#xff1a;桥接模式小结 在 Day 13 中&#xff0c;我们学习了桥接模式&#xff08;Bridge Pattern&#xff09;&#xff1a; 用于将“抽象”与“实现”分离&#xff0c;适用于双维度变化场景&#xff08;如图形类型 渲染方式&#xff09;。它强调…...

RMSIN论文阅读

自适应旋转卷积 (ARC)是否可以换成可变形卷积 研究背景 指向性遥感图像分割&#xff08;RRSIS&#xff09;&#xff1a;旨在根据文本描述实现遥感图像中目标对象的像素级定位 像素级定位&#xff1a;像素级定位指的是在图像中对目标对象的每个像素进行准确的定位和标记。这意味…...

【音视频】FLV格式分析

FLV概述 FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式&#xff0c;由于其封装后的⾳视频⽂件体积⼩、封装简单等特点&#xff0c;⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤FLV格式封装的⽂件后缀为.flv。 FLV封装格式是由⼀个⽂件头(file header)和…...

华为OD机试真题——最小的调整次数/特异性双端队列(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《最小的调…...

华为OD机试真题——统计匹配的二元组个数(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《统计匹配…...

4.16学习总结

完成134. 加油站 - 力扣&#xff08;LeetCode&#xff09;算法题 学习了filewriter的相关方法&#xff0c;了解了字符流的底层原理...

java面试篇 4.9

目录 mybatis&#xff1a; 1、mybatis的执行流程 2、mybatis是否支持延迟加载&#xff1f; 当我们需要去开启全局的懒加载时&#xff1a; 3、mybatis的一级和二级缓存 微服务 1、springcloud五大组件有哪些 2、服务注册和发现是什么意思&#xff1f;springcloud如何实现…...

子函数嵌套的意义——以“颜色排序”为例(Python)

多一层缩进精减参数传递&#xff0c;参数少平铺书代码写更佳。 笔记模板由python脚本于2025-04-16 11:52:53创建&#xff0c;本篇笔记适合喜欢子函数嵌套结构代码形式的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅…...

Python深度学习实现验证码识别全攻略

放在前面 Python深度学习实现验证码识别全攻略 Python深度学习实现验证码识别全攻略 在网络安全领域&#xff0c;验证码作为人机区分的关键防线&#xff0c;广泛应用于登录、注册等场景。随着技术演进&#xff0c;验证码样式愈发复杂&#xff0c;传统识别手段力不从心&#…...

【Linux】su、su-、sudo、sudo -i、sudo su - 命令有什么区别?分别适用什么场景?

目录 su su- sudo sudo -i sudo su - /etc/sudoers su 该命令将启动非登录shell&#xff0c;即虽然以该用户身份启动shell&#xff0c;但使用的是原始用户的环境设置。普通用户账户运行 su 命令切换到另一用户账户&#xff0c;需提供要切换的账户的密码。root用户&…...

算法-同余原理

在计算n个数相加或者相乘再取余时&#xff0c;中间结果可能会溢出导致结果错误&#xff0c;这时可以使用同余原理 一、同余原理 ①加法同余 &#xff08;a[1] a[2] ... a[n]&#xff09;% m > (a[1] % m a[2] % m ... a[n] % m) % m ② 乘法同余 &#xff08;…...

深入理解卷积神经网络(CNN):从原理到实践

引言 卷积神经网络(Convolutional Neural Networks, CNN)是深度学习领域最具影响力的架构之一&#xff0c;尤其在计算机视觉任务中表现出色。自2012年AlexNet在ImageNet竞赛中一战成名以来&#xff0c;CNN不断演进&#xff0c;推动着图像识别、医疗影像分析、自动驾驶等领域的快…...

深度学习常见模块实现001

文章目录 1.学习目的2.常见模块使用与实现2.1 ResNet18实现2.2 SeNet模块2.3 CBAM模块 1.学习目的 深度学习在图像处理这块&#xff0c;很多模块已经成型&#xff0c;并没有很多新的东西&#xff0c;更多的是不同的模块堆叠&#xff0c;所以需要我们不断总结&#xff0c;动手实…...

Python实现贪吃蛇三

上篇文章Python实现贪吃蛇一&#xff0c;实现了一个贪吃蛇的基础版本。后面第二篇文章Python实现贪吃蛇二修改了一些不足&#xff0c;但最近发现还有两点需要优化&#xff1a; 1、生成食物的时候有概率和记分牌重合 2、游戏缺少暂停功能 先看生成食物的时候有概率和记分牌重合的…...

windows server C# IIS部署

1、添加IIS功能 windows server 2012、windows server 2016、windows server 2019 说明&#xff1a;自带的是.net 4.5 不需要安装.net 3.5 尽量使用 windows server 2019、2016高版本&#xff0c;低版本会出现需要打补丁的问题 2、打开IIS 3、打开iis应用池 .net 4.5 4、添…...

LLM小白自学笔记:1.两种指令微调

一、LoRA 简单来说&#xff0c;LoRA不直接调整个大模型的全部参数&#xff08;那样太费资源&#xff09;&#xff0c;而是在模型的某些层&#xff08;通常是注意力层&#xff09;加个“旁路”——两个小的矩阵&#xff08;低秩矩阵&#xff09;。训练时只更新这俩小矩阵&#x…...

杰弗里·辛顿:深度学习教父

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 杰弗里辛顿&#xff1a;当坚持遇见突破&#xff0c;AI迎来新纪元 一、人物简介 杰弗…...

RHCE 第一次作业

一.定义延迟任务 1.安装邮件服务 [roothaiou ~]# yum install s-nail -y 2.配置邮件服务 [roothaiou ~]# vim /etc/mail.rc 3.测试邮件服务 [roothaiou ~]# echo 88888888 | mail -v -s Passion 13571532874163.com 4.设置定时任务 [roothaiou ~]# crontab -e 二.时间同步…...

库洛游戏一面+二面

目录 一面 1. ArrayList和LinkedList的区别&#xff0c;就是我在插入和删除的时候他们在时间复杂度上有什么区别 2. hashmap在java的底层是怎么实现的 3. 红黑树的实现原理 4. 红黑树的特点 5. 为什么红黑树比链表查询速度快 6. 在java中字符串的操作方式有几种 7. Stri…...

基于多模态深度学习的亚急性脊髓联合变性全流程预测与个性化管理技术方案

目录 技术方案文档1. 数据收集与预处理模块2. 多模态预测模型构建3. 术前风险评估系统4. 术中实时监测系统5. 术后并发症预测与护理6. 统计分析与验证模块7. 健康教育系统技术实现说明技术方案文档 1. 数据收集与预处理模块 功能:构建数据管道,清洗并整合多源数据 伪代码示…...

蓝桥杯日期的题型

做题思路 一般分为3个步骤,首先要定义一个结构体来存储月份的天数,第一循环日期,第二判断日期是否为闰年,第三就是题目求什么 结构体 static int[] ds{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 判断是否闰年的函数 public static void f(int m,int d){//被4整…...

【树形dp题解】dfs的巧妙应用

【树形dp题解】dfs的巧妙应用 [P2986 USACO10MAR] Great Cow Gathering G - 洛谷 题目大意&#xff1a; Bessie 正在计划一年一度的奶牛大集会&#xff0c;来自全国各地的奶牛将来参加这一次集会。当然&#xff0c;她会选择最方便的地点来举办这次集会。 每个奶牛居住在 N N …...

《AI大模型应知应会100篇》第20篇:大模型伦理准则与监管趋势

第20篇&#xff1a;大模型伦理准则与监管趋势 摘要 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;尤其是大模型&#xff08;如GPT、PaLM等&#xff09;在自然语言处理、图像生成等领域的广泛应用&#xff0c;AI伦理问题和监管挑战日益凸显。本文将梳理当…...

线上教学平台(vue+springboot+ssm+mysql)含文档+PPT

线上教学平台&#xff08;vuespringbootssmmysql&#xff09;含文档PPT 该系统是一个在线教学平台&#xff0c;主要分为管理员和学员两个角色&#xff1b;管理员界面包含首页、交流中心、学员管理、资料类型管理、学习资料管理、交流论坛、我的收藏管理、留言板管理、考试管理…...

Being-0:具有视觉-语言模型和模块化技能的人形机器人智体

25年3月来自北大、北京智源和 BeingBeyond 的论文“Being-0: A Humanoid Robotic Agent with Vision-Language Models and Modular Skills”。 构建能够在现实世界具身任务中达到人类水平表现的自主机器人智体&#xff0c;是人形机器人研究的终极目标。近期&#xff0c;基于基…...

Fiddler 进行断点测试:调试网络请求

目录 一、什么是断点测试&#xff1f; 二、Fiddler 的断点功能 三、如何在 Fiddler 中设置断点&#xff1f; 步骤 1&#xff1a;启动 Fiddler 步骤 2&#xff1a;启用断点 步骤 3&#xff1a;捕获请求 步骤 4&#xff1a;修改请求或响应 四、案例&#xff1a;模拟登录失…...