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

Linux 线程(上)

前言:大家早上中午晚上好!!今天来学习一下linux系统下所谓的线程吧!!!

一、重新理解进程,什么是进程?

1.1 图解

其中黑色虚线部分一整块就是进程,注意:一整块指的是:①:从一个程序运行起来后成为进程,OS堆这个进程进行描述PCB结构、②这个PCB中的进程地址空间所映射的物理内存资源、③页表,等等。。。总而言之:所有保证这个进程正常运行的所有资源!!

也就是说:进程是系统资源分配的基本单位,每一个进程的资源由系统分配,分配出来后的整一块资源都属于进程,进程相当于大家庭

1.2、Linux系统下的线程

图解:

图中通过第一个创建的PCB描述出来的PCB2、PCB3、PCB4、PCB5暂时可以把它理解为线程!!(注意:只是暂时把它认为是线程);

这些通过主线程描述出来的PCB2、3、4、5.....等他们共同瓜分进程地址空间,而这个地址空间就是资源的窗口(通过页表跟物理内存建立一一映射关系),所以相当于同一进程下所有线程在同一块资源下进行瓜分,然后这些线程就可以分别执行自己的任务!!!(所以线程相当于家庭中的每一个成员:爸爸、妈妈、爷爷、奶奶、哥哥、姐姐、等!!)

1.3线程的调度

创建并完成资源分配后,cpu就可以对一个个PCB进行调度了,让他们分别执行代码中的某一部分内容,各自完成自己的任务!!所以:线程是cpu调度的基本单位

二、pthread库

2.1、pthread库是什么先不管,先用,先写一段代码

写一段代码实现创建一个线程,并让它执行自己的任务:

写之前先介绍一个创建线程的接口:

首先第一个参数为:输出型参数,需要自己定义pthread_t 类型变量,把这个变量地址传入,创建完成后获取到pthread_t;

第二个参数:线程属性,不需要修改设置为nullptr即可;

第三个参数:线程的入口函数,这个线程一被调用就会从入口函数开始执行,这个函数自己定义,这个函数的返回值是void*类型,参数为void*类型;

第四个参数:给入口函数传送的形参,如果不许要传设置为nullptr;

创建完线程,线程跑完后要对线程进程回收;

介绍一个等待线程的接口:

第一个参数:为线程的tid,传入哪个tid就等待哪个线程;

第二个参数为:获取这个线程的退出信息,如果不需要设置为nullptr;

返回值int:如果等待成功返回0,如果失败返回错误码;

有了这两个接口我们就来写一段代码吧:

#include <iostream>
using namespace std;
#include <pthread.h>
#include <unistd.h>
void* print(void* args)
{int cnt=10;while(cnt--){cout<<"i am a thread !!!!"<<endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,print,nullptr);//线程创建int cnt2=10;while(cnt2--){cout<<"i am a main thread!!!!"<<endl;sleep(1);}int n=pthread_join(tid,nullptr);//线程等待if(n==0)cout<<"wait success!!!"<<endl;return 0;
}

当我们编译的时候发现报错:

原因是因为pthread.h是动态库,我们编译的时候需要加上 -lpthread 才能链接成功:

makefile:

mythread:mythread.ccg++ -o $@ $^ -std=c++11 -lpthread   //编译时加上-lpthread
.PHONY:clean
clean:rm -f mythread

编译成功并生成mythread可执行程序:

运行:

我们看到主线程和分线程分别打印了10次,并成功等待了线程;

2.2 批量创建线程

上面我们创建的是一个线程,如果我们想批量创建线程呢?

那很简单,用一个for循环创建线程同时把tid保存起来,再用一个for循环等待tid:

同时我们每个线程获取一下pid_t(进程pid),同时每个线程获取一下pthread_t(tid),同时用轻量级命令 :ps- aL 查看所有轻量级进程:

#include <iostream>
using namespace std;
#include <pthread.h>
#include <unistd.h>
#include <vector>
#define THREAD_NUM 5
void* print(void* args)
{cout<<"i am a thread !!!! tid is :"<<pthread_self()<<"  pid is:"<<getpid()<<endl;sleep(1);return nullptr;
}
int main()
{vector<pthread_t> tids;//批量创建线程并保存tidfor(int i=0;i<THREAD_NUM;i++){pthread_t tid;pthread_create(&tid,nullptr,print,nullptr);tids.push_back(tid);}for(int i=0;i<THREAD_NUM;i++){int n=pthread_join(tids[i],nullptr);//线程批量等待if(n==0)cout<<"wait success!!!  tid is : "<<tids[i]<<endl;}return 0;
}

编译后运行:

同时命令行输入ps - aL:

我们发现所有线程它的pid 都是相同的,tid是一串很长的数字且都是不相同的,用ps -aL命令查看到LWP中只一个数字15304是跟pid一样其他都不相同!!

pthread_t tid 究竟是什么?LWP是什么?他们跟PID之间的关系是什么?还有pthread库又是什么?

2.3重新理解线程

①:在linux系统下一般把线程称为轻量级进程,因为在Linux内核中没有用新的数据结构来描述线程,而是通过原有的进程PCB来描述线程的!!

②: 因此linux系统是通过LWP来对这些所谓的 “线程” 进行调度的,LWP就是:light weight process (轻量级进程的意思),所以在linux下所谓的线程:就是一个个通过(第一个创建出来的进程的PCB)描述出来的轻量级进程!

③: 那么linux系统不创建新的数据结构来描述线程,等于linux不想管理这些线程,那么谁来管理?pthread库!!来了!pthread库是第三方库,当我们安装linux操作系统的时候必须把pthread库安装好,这个pthread库里有别人编写好的一系列对线程操作的接口,且这个库需要管理每一个用户创建出来的线程!!!怎么管理?->先描述再组织!->pthread库必须有一个描述线程的数据结构(TCB)->pthread库通过对一个个TCB的管理从而管理一个个线程!!

④线程由pthread库管理,pthread库不属于OS内核,所以线程不属于OS内核!!在linux下所谓的线程是用户级线程!!

当pthread库调用一系列的pthread_create、pthread_join、等接口时其底层调用的其实是clone这个系统调用接口:

图解:

所以我们可以回答上面的第一个问题了:pthread_t tid 究竟是什么:

pthread_t tid 是用户级线程的tid!!所谓用户级就是管理线程的pthread库属于用户级!!每一个TCB有其对应的tid,用户通过tid便可以指定对某个线程进行操作!!

然后我们还能回答第二个问题了:LWP是什么:

图解:

我们知道每个PCB都有它的PID,linux下的“线程”是通过进程的PCB描述出来的;

当它被描述出来之后就是一个所谓的“线程”了,也就是称为了cup调度的基本单位

而PID代表的是进程,所谓进程代表的是被分配到的整块资源所有“线程”共享的这一个块资源

因此所有的“线程”的PID只有一个!!这些新创建出来的“线程”所以用LWP来标志!!

如果LWP跟PID一样说明这是第一个被创建出来的“线程”,即主线程!!!

最后cup就能通过LWP调度到每个它想调度的“线程”!!

同时我们可以回答第三个问题:pthread库是什么:

因为linux内核不管理线程,所以linux中把线程称之为:轻量级进程(它管理的是进程);

因为线程需要被管理,所以linux必须安装有pthread库;

pthread库就是用来管理用户创建除了的一切线程;

既然要管理所以pthread库必须对线程进行描述,必须要有TCB结构,通过一个个TCB结构的管理实现对所有线程的管理;

因此Linux下的所谓线程其实是用户级线程,那么我们可以这么认为:Linux下的线程=LWP(linux内核中的PCB轻量级进程标志)+pthread_t TID(用户中的TCB线程的标志);

三、线程的控制

3.1 线程的分离

如果主线程不想等待分支线程,我们可以让线程自己分离,分离后由OS进行;

线程分离接口:

#include<pthread.h>
int pthread_detach(pthread_t thread);
//1. 这是用来分离线程的pthread库接口
//2. thread:你想分离的线程的tid
//3. 返回值int,如果分离成功返回0,如果分离错误返回错误码

获取当前线程tid接口:

#include <pthread.h>
pthread_t pthread_self(void);
//1. pthread_t 返回值如果获取成功返回当前线程的tid

代码:

我们分离的同时等待一下线程看看能否等待成功:

线程分离的两种方法:线程自己分离

#include <iostream>
using namespace std;
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <cstring>
#define THREAD_NUM 5
void* print(void*args)
{pthread_detach(pthread_self());cout<<"i am a thread!!"<<endl;return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,print,nullptr);sleep(1);//等待1s让线程分离完成int code=pthread_join(tid,nullptr);if(code==0){cout<<"wait success !!"<<endl;}elsecout<<"wait false!! error num is:" <<code<<"error message :"<<strerror(code)<<endl;return 0;
}

编译运行:

线程分离成功,主线程等待失败,返回22错误码,意思是无效的参数,也就是没有等待到对应的tid;

线程分离方法二:主线程让他分离:

编译运行:

结果一样,说明成功分离分支线程;

3.2 线程的退出

线程退出的几种方式:

①线程运行完走到return 正常退出;

②终止线程的接口:

#include<pthread.h>
void pthread_exit(void* retval);
//1. retval 可以传入退出信息,由外部线程等待函数获取

我们退出的同时可以传入参数retval让主线程获取退出信息:

主线程等待获取线程退出信息需要传入一一个二级参数,因为join的第二个参数是一个输出型参数:

void* print(void*args)
{cout<<"i am a thread!!"<<endl;pthread_exit((void*)100);return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,print,nullptr);sleep(1);void*retval;pthread_join(tid,&retval);(long long int)retval;printf("%d\n",retval);return 0;
}

编译运行:

100退出码被带了出来;

③还有一个线程会终止的场景:当同一线程组内的任一线程出现异常,接收到终止信号,那么整个进程会崩溃,所有线程都会退出;

3.3 线程的取消

主线程可以取消一个线程,前提是这个线程已经被启动:

取消线程的接口:

#include<pthread.h>
int pthread_cancel( pthread_t thread);
//1. 取消一个线程,前提这个线程被启动
//2. thread : 需要取消的线程的tid
//3. 如果成功返回0,失败返回一个错误码
void* print(void*args)
{while(true){cout<<"i am a thread!!"<<endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,print,nullptr);int code= pthread_cancel(tid);if(code==0){cout<<"取消成功"<<endl;}elsecout<<"取消失败"<<endl;//sleep(1);//线程已被启动pthread_join(tid,nullptr);return 0;
}

运行:

四、总结线程的特点

4.1 、线程是系统调度的基本单位,进程是资源分配的基本单位;
4.2、线程的粒度小于进程,占用资源更少,因此通常多线程比多进程更高效;
4.3、线程没有独立的地址空间,线程是划分进程的地址空间,本质上使用的是同一地址空间!线程不拥有系统资源,线程共享进程的资源!
4.4、大量的计算使用多线程和多进程都可以实现并行/并发处理,区别在于线程的资源消耗小于进程,线程的稳定性不如进程,因此需要具体更细致的需求场景;
4.5、线程除了独立的栈空间和一组寄存器(保存线程的上下文)其他线程看不到之外其他所有资源都是所有线程共享的;
4.6、线程的通信速度更快,切换更快,因为他们在同地址空间内,且还共享了很多其他进程资源,比如页表指针,这些是不需要切换的!

今天的分享就到这里!如果对你有所帮助记得点赞收藏+关注哦!!谢谢!!!

咱下期见!!!

相关文章:

Linux 线程(上)

前言&#xff1a;大家早上中午晚上好&#xff01;&#xff01;今天来学习一下linux系统下所谓的线程吧&#xff01;&#xff01;&#xff01; 一、重新理解进程&#xff0c;什么是进程&#xff1f; 1.1 图解 其中黑色虚线部分一整块就是进程&#xff0c;注意&#xff1a;一整…...

# 终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法

终端执行 java -jar example.jar 时&#xff08;example.jar为项目jar包&#xff09;报错&#xff1a;“没有主清单属性” 的解决方法 在Java中&#xff0c;一个JAR文件必须包含一个主清单属性&#xff08;Main-Class属性&#xff09;才能在命令行中直接运行。如果你在尝试运行…...

4:OpenCV—保存图像

将图像和视频保存到文件 在许多现实世界的计算机视觉应用中&#xff0c;需要保留图像和视频以供将来参考。最常见的持久化方法是将图像或视频保存到文件中。因此&#xff0c;本教程准备解释如何使用 OpenCV C将图像和视频保存到文件中。 将图像保存到文件 可以学习如何保存从…...

[C++面试] const相关面试题

1、非 const 的引用必须指向一个已存在的变量 int main() {int &a 20; // 错误const int &b 30; } 字面量 20 是临时值&#xff08;右值&#xff09;&#xff0c;没有明确的内存地址。非常量引用&#xff08;左值引用&#xff09;不能直接绑定到右值&#xff08;如…...

#Redis黑马点评#(六)Redis当中的消息队列

目录 Redis当中的消息队列 一 基于List 二 基于PubSub 三 基于Stream 单消费模式 消费者组 Redis当中的消息队列 消息队列&#xff0c;字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色&#xff1a; 消息队列&#xff1a;存储和管理消息&#xff0c;也称为…...

Git基础原理和使用

Git 初识 一、版本管理痛点 在日常工作和学习中&#xff0c;我们经常遇到以下问题&#xff1a; - 通过不断复制文件来保存历史版本&#xff08;如报告-v1、报告-最终版等&#xff09; - 版本数量增多后无法清晰记住每个版本的修改内容 - 项目代码管理存在同样问题 二、版本控…...

Java程序员学AI(一)

一、前言 最近刷技术圈&#xff0c;满眼都是 GPT、DeepSeek、QWen 这些 AI 名词。看着同行们在群里聊 AI 写代码、做数据分析&#xff0c;我这个摸了 Java 老程序员突然慌了 —— 再不出手&#xff0c;怕是真要被时代落下了&#xff01; 作为一个 Java 死忠粉&#xff0c;学 …...

《Python星球日记》 第91天:端到端 LLM 应用(综合项目:医疗文档助手)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、项目概述与需求分析1. 项目背景2. 项目目标3. 技术栈概览二、数据准备与处理1. 文档收集策略2. 文本预处理流程3. 向量化与知识库构建三、模…...

目前主流的AI测试工具推荐

以下是目前备受关注的AI测试工具及平台&#xff0c;涵盖功能测试、视觉测试、性能测试及国产化解决方案等多个领域&#xff0c;结合其核心特性与适用场景进行综合推荐&#xff1a; 一、主流AI测试工具推荐 Testim 核心功能&#xff1a;基于AI的动态元素定位技术&#xff0c;…...

vscode优化使用体验篇(快捷键)

本文章持续更新中 最新更新时间为2025-5-18 1、方法查看方法 1.1当前标签跳到新标签页查看方法实现 按住ctrl 鼠标左键点击方法。 1.2使用分屏查看方法实现(左右分屏) 按住ctrl alt 鼠标左键点击方法。...

uniprot中PTM数据的下载

首先是PTM的介绍&#xff1a; 参考&#xff1a;https://en.wikipedia.org/wiki/Post-translational_modification 蛋白质的翻译后修饰&#xff08;PTM&#xff09;通过改变氨基酸残基的化学结构&#xff0c;显著影响其带电性质&#xff0c;从而调控蛋白质的功能、定位和相互作…...

【QGIS二次开发】地图编辑-04

系列目录&#xff1a; 【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客 【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客 【QGIS二次开发】地图符号与色表-03-CSDN博客 4 地图编辑 4.1 添加点要素 功能演示&#xff1a; 运行程序后…...

Qt 信号和槽-核心知识点小结(11)

目录 小结表格索引 disconnect函数 lambda表达式 啥是耦合&#xff0c;啥是内聚 简介&#xff1a;这是Qt信号和槽的最后一篇文章&#xff0c;最主要的是总结该信号和槽的核心知识点。以及该核心知识点的文章索引&#xff08;表格太长了&#xff0c;手机可能看不完整&#…...

React响应事件中onClick={handleClick} 的结尾有没有小括号的区别

你可以通过在组件中声明 事件处理 函数来响应事件&#xff1a; function MyButton() {function handleClick() {alert(You clicked me!);}return (<button onClick{handleClick}>点我</button>);} 注意&#xff0c;onClick{handleClick} 的结尾没有小括号&#x…...

React-Query使用react-testing-library进行测试

1.测试react-query首先我们必须得拥有queryClient&#xff0c;所以我们初始化queryClient&#xff0c;因为默认是重试三次&#xff0c;这意味着如果想测试错误的查询&#xff0c;测试可能会超时。所以可以在初始化时关闭 const createWrapper () > {const queryClient new…...

软件设计师CISC与RISC考点分析——求三连

一、考点分值占比与趋势分析&#xff08;CISC与RISC&#xff09; 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…...

GO语言(一期)常用关键字总结

GO语言&#xff08;主题一&#xff09;常用关键字总结 我们这里列出一些go语言关键字&#xff0c;方便各位友友们检查一下自己的学习效果&#xff0c;也方便友友们学习查询。 break default func interface select case defer go map …...

Ubuntu搭建NFS服务器的方法

0 工具 Ubuntu 18.041 Ubuntu搭建NFS服务器的方法 在Ubuntu下搭建NFS&#xff08;网络文件系统&#xff09;服务器可以让我们像访问本地文件一样访问Ubuntu上的文件&#xff0c;例如可以把开发板的根文件系统放到NFS服务器目录下方便调试。 1.1 安装nfs-kernel-server&#…...

京东商品详情API接口开发指南(含Java/Python实现)

接口概述 京东开放平台提供了商品详情查询接口&#xff0c;开发者可以通过SKUID获取商品的详细信息&#xff0c;包括标题、价格、图片、促销信息等。该接口需要申请API权限和认证密钥。 点击获取key和secret 接口特点 支持批量查询&#xff08;最多20个SKU&#xff09;返回J…...

二叉树构造:从前序、中序与后序遍历序列入手

目录 引言 从前序与中序遍历序列构造二叉树&#xff08;题目 105&#xff09; 解题思路 举例说明 从中序与后序遍历序列构造二叉树&#xff08;题目 106&#xff09; 解题思路 举例说明 总结 引言 二叉树的遍历与构造是算法领域中的经典问题。LeetCode 上的“从前序与中…...

GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法

本文介绍在谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;中&#xff0c;批量下载逐日的ERA5土壤湿度数据&#xff08;或者是其他气象数据、遥感影像数据等&#xff09;的方法。 首先&#xff0c;明确一下本文的需求。我们希望在GEE中&#xff0c;下…...

C#接口(Interface)全方位讲解:定义、特性、应用与实践

引言 在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;接口&#xff08;Interface&#xff09;是一种重要的结构&#xff0c;它定义了某一类对象或类应遵循的行为规范。接口强调“做什么&#xff08;What&#xff09;”&#xff0c;而非“怎么做&#xff08;How&…...

索引与数据结构、并行算法

3. 索引与数据结构 索引类比目录&#xff1a;类似于书籍目录&#xff0c;帮助我们快速定位信息。索引的核心目的&#xff1a;提升数据查找效率&#xff0c;优化增删改查性能。实际应用广泛&#xff1a;MySQL、Redis、搜索引擎、分布式系统、中间件等。 3.1. 索引设计中的需求…...

GC全场景分析

GC全场景分析 文章目录 GC全场景分析标记-清除法**标记 - 清除法核心流程与 STW 机制****标记 - 清除法四步流程****1. STW 启动&#xff08;暂停用户线程&#xff09;****2. 标记可达对象&#xff08;从根集合出发&#xff09;****3. 清除未标记对象&#xff08;回收堆内存&am…...

OSI七层模型和TCP/IP的五层(四层模型)

分层 1.什么是分层 我理解是对同一相同或者相似的事务或者操作功能进行分类&#xff0c;比如我们去餐厅吃饭&#xff0c;就可以分为好多层&#xff0c;客户层&#xff0c;服务员层&#xff0c;前台层&#xff0c;后厨层&#xff0c;每一层都专注自己的事情&#xff0c;客户层…...

MouseDown,MouseUp,LostMouseCapture的先后顺序

本文目标是实现如下功能: 按下一个按钮后置位某变量;鼠标松开后复位某个变量? 看似简单,但是一般来说会存在如下两种现象: 鼠标移出按钮:默认会丢失鼠标事件跟踪,即MouseLeftButtonUp事件并不会被触发。 焦点切换:Tab 键切换焦点会干扰按钮的事件捕获 本文通过几个…...

第8章 常用实用类

8.1 String类 在java.lang包&#xff08;默认引入&#xff09;中&#xff0c;可直接使用。 定义为final类&#xff0c;不能扩展String类&#xff0c;不可以继承&#xff0c;不可以有子类。 8.1.1 构造String对象 常量对象&#xff1a; 英文双引号括起来 String常量放入常…...

视差场(disparity field)

视差场&#xff08;disparity field&#xff09;是立体视觉中的一个重要概念&#xff0c;用于描述两幅立体图像之间像素的对应关系。以下是对视差场的详细解释&#xff1a; 1. 视差&#xff08;Disparity&#xff09;的定义 视差是指同一场景点在两幅立体图像中的像素位置差异…...

AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》

AI&#xff1a;OpenAI论坛分享—《AI重塑未来&#xff1a;技术、经济与战略》 导读&#xff1a;2025年4月24日&#xff0c;OpenAI论坛全面探讨了 AI 的发展趋势、技术范式、地缘政治影响以及对经济和社会的广泛影响。强调了 AI 的通用性、可扩展性和高级推理能力&#xff0c;以…...

【已经解决诸多问题】Mamba安装

mamba被称为新一代的计算架构&#xff0c;因此在CV和时序领域存在诸多的方案开始采用这一新架构&#xff0c;但是这个架构的安装过程中存在诸多问题&#xff01;&#xff01;&#xff01;&#xff01;为了更好帮助大家理解我们给出一个统一的安装流程&#xff01;&#xff01;&…...

计算机的基本组成与性能

1. 冯诺依曼体系结构&#xff1a;计算机组成的金字塔 1.1. 计算机的基本硬件组成 1.CPU - 中央处理器&#xff08;Central Processing Unit&#xff09;。 2.内存&#xff08;Memory&#xff09;。 3.主板&#xff08;Motherboard&#xff09;。主板的芯片组&#xff08;Ch…...

“绿色邮政,智能九识”——呼和浩特邮政无人快递车发车,驶向智慧物流新时代!

5月12日&#xff0c;“绿色邮政&#xff0c;智能九识”呼和浩特邮政无人驾驶快递车发车。 此次投运的邮政无人驾驶快递车实力惊人&#xff1a;单车运量超1000件&#xff0c;时速达40公里&#xff0c;通过智能路径规划实现24小时作业&#xff0c;与传统运输相比&#xff0c;运转…...

AGI大模型(24):通过LangChain的接口来调用OpenAI对话

1 创建对话 使用langchain库中的ChatOpenAI类来创建一个对话模型。 from dotenv import load_dotenvload_dotenv()import os from langchain_openai import ChatOpenAIllm = ChatOpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url="https://api.deepsee…...

大模型中的Token机制深度解析

目录 大模型中的Token机制深度解析 一、Token的本质与核心作用 二、主流分词算法对比 三、GPT-3分词机制详解 四、分词策略对模型性能的影响 五、工程实践建议 六、未来演进方向 一、Token的本质与核心作用 Token是大模型处理文本的​​最小语义单元​​,类似于人类语…...

【MySQL】库与表的操作

一、库的操作 1. 查看数据库 语法&#xff1a;show databases;这里的database是要加s的 查看当前自己所处的数据库&#xff1a;select database(); 例如下图&#xff0c;我当前所处的数据库就是在class1数据库 2. 创建数据库 语法&#xff1a;create database [if not e…...

创建指定版本的vite项目

1、获取vite的版本号 npm view create-vite versions 注:4.4.1版本即对应着node16版本的项目 2、创建制定版本的vite项目 npm init vite<version>...

java中的Servlet3.x详解

Servlet 3.x 是 Java Web 开发的重要里程碑&#xff0c;包含 Servlet 3.0&#xff08;2009年发布&#xff09;和 Servlet 3.1&#xff08;2013年发布&#xff09;两个主要版本。它通过多项革新优化了开发效率、性能及扩展性&#xff0c;成为现代 Java Web 应用的核心技术基础。…...

单目测距和双目测距 bev 3D车道线

单目视觉测距原理 单目视觉测距有两种方式。 第一种&#xff0c;是通过深度神经网络来预测深度&#xff0c;这需要大量的训练数据。训练后的单目视觉摄像头可以认识道路上最典型的参与者——人、汽车、卡车、摩托车&#xff0c;或是其他障碍物&#xff08;雪糕桶之类&#xf…...

weibo_comment_pc_tool | 我于2025.5月用python开发的评论采集软件,根据帖子链接爬取评论的界面工具

本工具仅限学术交流使用&#xff0c;严格遵循相关法律法规&#xff0c;符合平台内容的合法及合规性&#xff0c;禁止用于任何商业用途&#xff01; 一、背景分析 1.1 开发背景 微博&#xff08;以下简称wb&#xff09;是国内极具影响力的社交媒体平台&#xff0c;具有内容形式…...

ubuntu防火墙命令和放行ssh端口

一、关闭UFW防火墙&#xff08;Ubuntu默认工具&#xff09; 1. 临时关闭防火墙 sudo ufw disable sudo ufw status # 显示 Status: inactive 表示已关闭 2. 永久禁用防火墙&#xff08;禁用系统服务&#xff09; sudo systemctl stop ufw # 立即停止服务 sudo sy…...

PWM讲解+STM32任意频率、占空比、脉宽生成函数介绍

1.PWM讲解 脉冲宽度调制(PWM)&#xff0c;是英文“Pulse Width Modulation”的缩写&#xff0c;简称脉宽调制。 脉宽调制 最开始使用PWM时&#xff0c;是做智能车时使用的舵机打角&#xff0c;电机驱动。这都属于比较浅显&#xff0c;普通的应用。下面和大家简单分享一下PWM的…...

C++23 范围迭代器作为非范围算法的输入 (P2408R5)

文章目录 一、引言二、C23及范围迭代器的背景知识2.1 C23概述2.2 范围迭代器的概念 三、P2408R5提案的内容3.1 提案背景3.2 提案内容 四、范围迭代器作为非范围算法输入的优势4.1 代码简洁性4.2 提高开发效率4.3 更好的兼容性 五、具体的代码示例5.1 使用范围迭代器进行并行计算…...

CVE-2018-1273 漏洞深度分析

漏洞概述 CVE-2018-1273 是 Spring Data Commons 中的一个高危远程代码执行&#xff08;RCE&#xff09;漏洞&#xff0c;影响版本为 Spring Data Commons 1.13–1.13.10 和 2.0–2.0.5。攻击者通过构造包含恶意 SpEL表达式的 HTTP 请求参数&#xff0c;触发表达式注入&#x…...

C++23:修正常量迭代器、哨兵和范围

文章目录 引言C20范围库回顾C23之前常量迭代器的问题视图可能不传播const代理对象的复杂性泛型代码中的一致性 P2278R4提案及C23的改进std::views::as_const的工作原理代码示例 浅const视图&#xff08;如std::span&#xff09;的改进总结 引言 在C的发展历程中&#xff0c;每…...

【漫话机器学习系列】266.雅可比矩阵(Jacobian Matrix)

雅可比矩阵&#xff08;Jacobian Matrix&#xff09;详解 | 多变量函数微积分的基石 在深度学习、计算图、优化算法、机器人控制、流形学习等众多领域中&#xff0c;“雅可比矩阵&#xff08;Jacobian Matrix&#xff09;”是一个非常核心的数学工具。 这篇文章将结合一张视觉…...

Leetcode 3551. Minimum Swaps to Sort by Digit Sum

Leetcode 3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路2. 代码实现 题目链接&#xff1a;3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路 这一题思路上我实现的非常暴力&#xff0c;就是先求出正确的排列&#xff0c;然后从头考察每一个元素是否处在其目标…...

西门子1200/1500博图(TIA Portal)寻址方式详解

西门子博图&#xff08;TIA Portal&#xff09;是西门子公司推出的自动化工程软件平台&#xff0c;广泛应用于工业自动化领域。在编写PLC程序时&#xff0c;寻址方式是一个非常重要的概念&#xff0c;它决定了如何访问和操作PLC中的数据和资源。本文将详细介绍西门子博图中的寻…...

STK手动建链+matlab联调

在右边场景区选择你要建链的卫星&#xff0c;右键在弹出的选项中选择Access 选择你要建链的卫星&#xff0c;这里我选择3轨10星与4轨8星建链&#xff0c;点击compute后再close就行了 建链完成&#xff0c;这里链路的颜色跟起始卫星的颜色一致&#xff0c;要想改变颜色只需改变卫…...

MATLAB中的Switch语句讲解

MATLAB中的Switch语句&#xff1a;一个简单的控制流工具 在MATLAB中&#xff0c;switch语句是一种多分支控制结构&#xff0c;通常用于根据某个表达式的值选择不同的代码块进行执行。它的作用类似于一系列的if-elseif-else语句&#xff0c;但在处理多个条件时&#xff0c;swit…...

【SpringBoot】✈️整合飞书群机器人发送消息

&#x1f4a5;&#x1f4a5;✈️✈️欢迎阅读本文章❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;本篇文章阅读大约耗时3分钟。 ⛳️motto&#xff1a;不积跬步、无以千里 &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;&#x1f381;&#x1f381;&am…...