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

线程概念与控制

Linux线程概念


什么是线程


在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部
的控制序列”,一切进程至少都有一个执行线程,线程在进程内部运行,本质是在进程地址空间内运行 在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化,透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

以前我们说的进程其实是只有一个线程的进程,叫轻量级进程PCB,每个进程有独立的页表,独立的虚拟内存,有自己的struct等数据结构

 多线程是进程内部的概念,复用task_struct,用进程来模拟线程,进程代码全部复用,各个轻量TCB级进程共享同一份资源,虚拟地址也是资源的代表,函数是虚拟地址(逻辑地址)空间的集合,就是让线程未来执行ELF程序的不同的函数即可

  分页式存储管理

 虚拟地址和页表的由来
思考⼀下,如果在没有虚拟内存和分页机制的情况下,每一个用户程序在物理内存上所对应的空间必须是连续的,如下图:

 因为每一个程序的代码、数据长度都是不一样的,按照这样的映射方式,物理内存将会被分割成各种离散的、大小不同的块。经过一段运行时间之后,有些程序会退出,那么它们占据的物理内存空间可以被回收,导致这些物理内存都是以很多碎片的形式存在。
怎么办呢?我们希望操作系统提供给用户的空间必须是连续的,但是物理内存最好不要连续。此时虚拟内存和分页便出现了,如下图所示:

 把物理内存按照一个固定的长度的页框进行分割,有时叫做物理页。每个页框包含一一个物理页
(page)。一个页的大小等于页框的大小。大多数 32位 体系结构至持 4KB 的页,而 64位 体系结
构一般会支持 8KB 的页。区分一页和页个页框是很重要的:

  • 页框是一个存储区域;
  • 而页是一个数据块,可以存放在任何页框或磁盘中。

有了这种机制,CPU 便并非是直接访问物理内存地址,而是通过虚拟地址空间来间接的访问物理内存地址。所谓的虚拟地址空间,是操作系统为每一个正在执行的进程分配的一个逻辑地址,在32位机上,其范围从0 ~ 4G-1。


操作系统通过将虚拟地址空间和物理内存地址之间建立映射关系,也就是页表,这张表上记录了每一对页和页框的映射关系,能让CPU间接的访问物理内存地址。


总结一下,其思想是将虚拟内存下的逻辑地址空间分为若干页,将物理内存空间分为若干页框,通过页表便能把连续的虚拟内存,映射到若干个不连续的物理内存页。这样就解决了使用连续的物理内存造成的碎片问题。

物理内存管理


假设一个可用的物理内存有 4GB 的空间。按照一个页框的大小 4KB 进行划分, 4GB 的空间就是
4GB/4KB = 1048576 个页框。有这么多的物理页,操作系统肯定是要将其管理起来的,操作系统
需要知道哪些页正在被使用,哪些页空闲等等。
内核用 struct page 结构表示系统中的每个物理页,出于节省内存的考虑, struct page 中使
用了大量的联合体union

/* include/linux/mm_types.h */
struct page {
/* 原⼦标志,有些情况下会异步更新 */
unsigned long flags;
union {
struct {
/* 换出⻚列表,例如由zone->lru_lock保护的active_list */
struct list_head lru;
/* 如果最低为为0,则指向inode
* address_space,或为NULL
* 如果⻚映射为匿名内存,最低为置位
* ⽽且该指针指向anon_vma对象
*/
struct address_space* mapping;
/* 在映射内的偏移量 */
pgoff_t index;
/*
* 由映射私有,不透明数据
* 如果设置了PagePrivate,通常⽤于buffer_heads
* 如果设置了PageSwapCache,则⽤于swp_entry_t
* 如果设置了PG_buddy,则⽤于表⽰伙伴系统中的阶
*/
unsigned long private;
};
struct {
/* slab, slob and slub */
union {
struct list_head slab_list; /* uses lru */
struct {
/* Partial pages */
struct page* next;
#ifdef CONFIG_64BIT
int pages; /* Nr of pages left */
int pobjects;
/* Approximate count */
#else
short int pages;
short int pobjects;
#endif
};
};
struct kmem_cache* slab_cache; /* not slob */
/* Double-word boundary */
void* freelist;
/* first free object */
union {
void* s_mem;
/* slab: first object */
unsigned long counters;
/* SLUB */
struct {
/* SLUB */
unsigned inuse : 16;
/* ⽤于SLUB分配器:对象的数⽬ */
unsigned objects : 15;
unsigned frozen : 1;
};
};
};
...
};
union {
/* 内存管理⼦系统中映射的⻚表项计数,⽤于表⽰⻚是否已经映射,还⽤于限制逆向映射搜
索*/
atomic_t _mapcount;
unsigned int page_type;
unsigned int active;
/* SLAB */
int units;
/* SLOB */
};
...
#if defined(WANT_PAGE_VIRTUAL)
/* 内核虚拟地址(如果没有映射则为NULL,即⾼端内存) */
void* virtual;
#endif /* WANT_PAGE_VIRTUAL */
...
}

其中比较重要的几个参数:

  • 1. flags :用来存放页的状态。这些状态包括页是不是脏的,是不是被锁定在内存中等。flag的每⼀位单独表示一种状态,所以它至少可以同时表示出32种不同的状态。这些标志定义在<linux/page-flags.h>中。其中一些比特位非常重要,如PG_locked用于指定页是否锁定,PG_uptodate用于表示页的数据已经从块设备读取并且没有出现错误。
  • 2. _mapcount :表示在页表中有多少项指向该页,也就是这一页被引用了多少次。当计数值变为-1时,就说明当前内核并没有引用这一页,于是在新的分配中就可以使用它。
  • 3. virtual :是页的虚拟地址。通常情况下,它就是页在虚拟内存中的地址。有些内存(即所谓的高端内存)并不永久地映射到内核地址空间上。在这种情况下,这个域的值为NULL,需要的时候,必须动态地映射这些页。

栈开辟空间后自底向上我们只需要知道起始位置+n*4KB就知道每个页表的位置了

页表


页表中的每一个表项,指向一个物理页的开始地址。在 32 位系统中,虚拟内存的最大空间是 4GB ,这是每一个用户程序都拥有的虚拟内存空间。既然需要让 4GB 的虚拟内存全部可用,那么页表中就需要能够表示这所有的 4GB 空间,那么就一共需要 4GB/4KB = 1048576 个表项。如下图所示:

 虚拟内存看上去被虚线“分割”成一个个单元,其实并不是真的分割,虚拟内存仍然是连续的。这个
虚线的单元仅仅表示它与页表中每一个表项的映射关系,并最终映射到相同大小的一个物理内存页
上。
页表中的物理地址,与物理内存之间,是随机的映射关系,哪里可用就指向哪里(物理页)。虽然最终使用的物理内存是离散的,但是与虚拟内存对应的线性地址是连续的。处理器在访问数据、获取指令时,使用的都是线性地址,只要它是连续的就可以了,最终都能够通过页表找到实际的物理地址。

在 32 位系统中,地址的⻓度是 4 个字节,那么页表中的每一个表项就是占用 4 个字节。所以页表占据的总空间大小就是: 1048576*4 = 4MB 的大小。也就是说映射表自己本身,就要占用 4MB /
4KB = 1024 个物理页。这会存在哪些问题呢?

  • 回想一下,当初为什么使用页表,就是要将进程划分为一个个页可以不用连续的存放在物理内存中,但是此时页表就需要1024个连续的页框,似乎和当时的目标有点背道而驰了......
  • 此外,根据局部性原理可知,很多时候进程在一段时间内只需要访问某几个页就可以正常运行了。因此也没有必要一次让所有的物理页都常驻内存。

解决需要大容量页表的最好方法是:把页表看成普通的文件,对它进行离散分配,即对页表再分页,由此形成多级页表的思想。

为了解决这个问题,可以把这个单一页表拆分成 1024 个体积更小的映射表。如下图所示。这样一
来,1024(每个表中的表项个数) * 1024(表的个数),仍然可以覆盖 4GB 的物理内存空间。

这里的每一个表,就是真正的页表,所以一共有 1024 个页表。一个页表自身占用 4KB ,那么
1024 个页表一共就占用了 4MB 的物理内存空间,和之前没差别啊?
从总数上看是这样,但是一个应用程序是不可能完全使用全部的 4GB 空间的,也许只要几十个页表就可以了。例如:一个用户程序的代码段、数据段、栈段,一共就需要 10 MB 的空间,那么使用 3 个页表就足够了。
计算过程:
每一个页表项指向一个 4KB 的物理页,那么一个页表中 1024 个页表项,一共能覆盖 4MB 的物理内存;
那么 10MB 的程序,向上对齐取整之后(4MB 的倍数,就是 12 MB),就需要 3 个页表就可以了。

页目录结构


到目前为止,每一个页框都被一个页表中的一个表项来指向了,那么这 1024 个页表也需要被管理起来。管理页表的表称之为页目录表,形成二级页表。如下图所示:

所有页表的物理地址被页目录表项指向,页目录的物理地址被 CR3 寄存器 指向,这个寄存器中,保存了当前正在执行任务的页目录地址。
所以操作系统在加载用户程序的时候,不仅仅需要为程序内容来分配物理内存,还需要为用来保存程序的页目录和页表分配物理内存。

两级页表的地址转换


下面以⼀个逻辑地址为例。将逻辑地址( 0000000000,0000000001,11111111111 )转换为物
理地址的过程:
1. 在32位处理器中,采用4KB的页大小,则虚拟地址中低12位为页偏移,剩下高20位给页表,分成两级,每个级别占10个bit(10+10)。
2. CR3 寄存器 读取页目录起始地址,再根据一级页号查页目录表,找到下一级页表在物理内存中
存放位置。
3. 根据二级页号查表,找到最终想要访问的内存块号。
4. 结合页内偏移量得到物理地址。

 注:一个物理页的地址一定是 4KB 对齐的(最后的 12 位全部为 0 ),所以其实只需要记录物理
页地址的高 20 位即可。
6. 以上其实就是 MMU 的工作流程。MMU(Memory Manage Unit)是一种硬件电路,其速度很快,
主要工作是进行内存管理,地址转换只是它承接的业务之⼀。
到这里其实还有个问题,MMU要先进行两次页表查询确定物理地址,在确认了权限等问题后,MMU再将这个物理地址发送到总线,内存收到之后开始读取对应地址的数据并返回。那么当页表变为N级时,就变成了N次检索+1次读写。可见,页表级数越多查询的步骤越多,对于CPU来说等待时间越长,效率越低。

flags标记位共32个字节前十个比特位拿着索引可以在页目录(存放下一级页表的地址)中找到对应的哪张页表(页的地址),然后通过中间的十个比特位索引找到对应的具体页的首位置,最后十二个比特位通过页内偏移找到页内具体的位置,CR3寄存器内保存当前上下文页目录的物理地址,PCB提供虚拟地址给CPU,MMU最终实现虚拟地址转化,进去是虚拟地址,出来就是实际的物理地址

单级页表对连续内存要求高,于是引入了多级页表,但是多级页表也是一把双刃剑,在减少连续存储要求且减少存储空间的同时降低了查询效率。
有没有提升效率的办法呢?计算机科学中的所有问题,都可以通过添加一个中间层来解决。 MMU 引入了新武器,江湖⼈称快表的 TLB (其实,就是缓存)
当 CPU 给 MMU 传新虚拟地址之后, MMU 先去问 TLB 那边有没有,如果有就直接拿到物理地址发到总线给内存,齐活。但 TLB 容量比较小,难免发生 Cache Miss ,这时候 MMU 还有保底的老武器页表,在页表中找到之后 MMU 除了把地址发到总线传给内存,还把这条映射关系给到TLB,让它记录一下刷新缓存。

 

相关文章:

线程概念与控制

Linux线程概念 什么是线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部 的控制序列”&#xff0c;一切进程至少都有一个执行线程&#xff0c;线程在进程内部运行&#xff0c;本质是在进程地址空间内…...

【SpringAI+阿里云百炼】AI对话4个Demo

基于SpringAI和阿里云百炼平台&#xff0c;实现了四个AI对话的小Demo 小团团对话机器人哄哄模拟器培训班智能客服仿ChatPDF 笔记如下:语雀知识笔记《SpringAI》...

Redis-----认识NoSQL

文章目录 前言一、SQL的结构化与NoSQL非结构化1.SQL2.NoSQL 二、关系型数据库SQL与非关系型数据库NoSQL1.SQL2.NoSQL 三、SQL查询与NoSQL查询1.SQL2.NoSQL 四、事务的区别1.SQL2.NoSQL 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 提示&#xff…...

驱动开发硬核特训 · Day 27(下篇):深入掌握 Common Clock Framework 架构与实战开发

节。 在本篇内容中&#xff0c;我们将围绕 Linux 内核中的时钟子系统核心架构 —— Common Clock Framework&#xff08;简称 CCF&#xff09;展开深入讲解&#xff0c;目标是帮助你全面理解其设计理念、主要数据结构、注册流程、驱动实现方式&#xff0c;以及如何基于 NXP i.M…...

Qt基础知识记录(终篇)

写在前面 博主的项目所需知识已经差不多学完了&#xff0c;后续如果还需要再学习那就继续学&#xff0c;毕竟程序员就是摸着石头过河的&#xff0c;碰壁乃是常有的事情。博主的项目服务器是用MySQL存储数据的&#xff0c;所以博主学习一下Qt如何连接MySQL及从MySQL中存取数据 博…...

LeetCode刷题链表

文章目录 链表总结 常用技巧两数相加题解代码 两两交换链表中的节点题解代码 重排链表题解代码 合并k个升序链表题解代码 K个一组翻转链表题解代码 链表总结 常用技巧 画图 直观 形象 便于理解引入虚拟头节点&#xff0c;便于处理边界情况&#xff0c;方便我们对链表进行…...

transfomer网络构建

目录 整体架构 详细模块分析 Transformer 算法的演进 代码讲解 1. 导入必要的库 2. InputEmbeddings 类 3. PositionalEncoding 类 4. LayerNormalization 类 5. FeedForwardBlock 类 6. MultiHeadAttentionBlock 类 7. ResidualConnection 类 8. EncoderBlock 类 9. Encoder 类…...

【mathematica】常见命令

mathematica官方文档 下载安装 安装激活教程 基本用法 输入、画图、基本运算、方程组求解、公式导出、 笔记本新建&#xff1a; 文件-新建-笔记本 输入&#xff1a; 直接在界面输入定义的变量、式子或者方程组即可 输出&#xff08;计算&#xff09; ENTER : 换行ENTER SHIF…...

photoshop学习笔记2

第一章 第01节-界面的重要性(学习方法) 第02节-文件的打开新建及储存 第03节-移动工具(图层概念) 学习目标&#xff1a; 1.了解图层概念 2.认识工具属性 3.掌握工具使用 图层的概念 移动工具 移动工具就是用来移动图层内容的。是否可以用来移动组…...

从软件到硬件:三大主流架构的特点与优劣详解

常见的架构包括软件架构、企业架构、硬件架构等&#xff0c;以下是对这几种常见架构的分析&#xff1a; 一、软件架构 1.分层架构 描述&#xff1a;分层架构是一种经典的软件架构模式&#xff0c;将软件系统按照功能划分为不同的层次&#xff0c;一般包括表现层&#xff08;…...

网狐旗舰大联盟组件源码私测笔记:结构分层、UI重构与本地实操全流程

作为一套衍生于传统网狐架构的源码版本&#xff0c;大联盟这套源码组件可谓是在经典基础上进行了深度重塑。与老版死板的框架风格不同&#xff0c;它不仅对界面做了大刀阔斧的重构&#xff0c;还在组件层级的组织上做了优化。本文将基于一整套源码进行深度解析&#xff0c;强调…...

Oracle OCP认证考试考点详解083系列07

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 31. 第31题&#xff1a; 题目 解析及答案&#xff1a; 从 Oracle 19c 开始&#xff0c;数据库配置助手&#xff08;DBCA&#xff09;在克…...

Qt .pro配置msvc相关命令(二)

目录 1. 指定编译器版本 2. 设置编译器选项 3. 设置链接器选项 4. 定义预处理器宏 5. 指定包含目录和库目录 6. 配置生成目标 7. 配置调试和发布模式 8. 指定生成文件的目录 9. 使用特定的 MSVC 功能 10. 条件编译 在 Qt 中&#xff0c;.pro 文件是项目配置文件&…...

Debezium Binlog解析与事件转换流程详解

Debezium Binlog解析与事件转换流程详解 1. Binlog解析整体流程 #mermaid-svg-2ghVgmGOnV4elpya {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2ghVgmGOnV4elpya .error-icon{fill:#552222;}#mermaid-svg-2ghVgmG…...

SpringBoot接口防抖(防重复提交)

目录 一.流程分析&#xff1a; 二.案例代码详解&#xff1a; 前提条件&#xff1a; 1.自定义注解&#xff1a; 2.编写异常类&#xff1a; 3.创建key生成器&#xff1a; 4.自定义AOP切面&#xff1a; 5.Controller&#xff1a; 三.Redission分布式解决方案&#xff1a;…...

HTML02:网页基本信息

网页的基本信息 DOCTYPE声明 < title 标签 < meat 标签 <!-- DOCTYPE:告诉浏览器&#xff0c;我们要使用什么规格 --> <!DOCTYPE html> <!-- head标签代表网页头部 --> <html lang"en"> <head><!-- meta描述性标签&#…...

uniswap v4 hooks标志位

hooks的代码位置在这&#xff0c;它是是组织校验&#xff0c;调用用户创建钩子的类库。 首先看其中定义的常量&#xff1a; uint160 internal constant ALL_HOOK_MASK uint160((1 << 14) - 1);uint160 internal constant BEFORE_INITIALIZE_FLAG 1 << 13;uint16…...

YOLOv7细节解读

RepVGG 推理加速 背景与动机&#xff1a;在模型的骨干网络&#xff08;backbone&#xff09;优化中&#xff0c;VGG 因结构简单&#xff0c;在显存利用上有优势&#xff08;单一路径&#xff0c;仅需一倍显存&#xff09;&#xff0c;但被多分支结构的 ResNet 超越。然而&#…...

nt!MiSessionAddProcess函数分析和nt!MmSessionSpace全局变量的关系

第一部分&#xff1a; 1: kd> g Breakpoint 42 hit nt!MiSessionAddProcess: 80ab2fbe 55 push ebp 1: kd> kc # 00 nt!MiSessionAddProcess 01 nt!MmCreateProcessAddressSpace 02 nt!PspCreateProcess 03 nt!NtCreateProcessEx 04 nt!_KiSystemServic…...

情绪ABC——AI与思维模型【93】

一、定义 情绪ABC思维模型是一种心理学上的理论&#xff0c;它认为人们的情绪和行为反应&#xff08;C&#xff0c;Consequence&#xff09;并非直接由激发事件&#xff08;A&#xff0c;Activating event&#xff09;引起&#xff0c;而是由个体对激发事件的认知和评价所产生…...

基于k8s系统的API网关-kong网关

1. 为什么需要 API 网关 API网关是一个服务器&#xff0c;是系统的唯一入口。API网关封装了系统内部架构&#xff0c;为每个客户端提供一个定制的API。它可能还具有其它职责&#xff0c;如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。API网关方式的核心要点…...

8.2 GitHub企业级PDF报告生成实战:ReportLab高级技巧与性能优化全解析

GitHub企业级PDF报告生成实战:ReportLab高级技巧与性能优化全解析 GitHub Sentinel 高级功能实现:PDF 报告生成技术详解 关键词:PDF 报告生成, ReportLab 实战, 结构化数据转换, 容器化字体配置, 企业级报告模板 1. 需求分析与技术选型 PDF 报告生成需要满足以下技术要求…...

一周学会Pandas2 Python数据处理与分析-Pandas2复杂数据查询操作

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 前面我们学了.loc[]等几个简单的数据筛选操作&#xff0c;但实际业务需求往 往需要按照一定的条件甚至复杂的组合条件…...

四年级数学知识边界总结思考-下册

目录 一、背景二、过程1.四则运算小学四年级课本下册《四则运算》知识点、由来、作用与意义解析**一、核心知识点****二、历史由来****三、作用与意义****四、总结** 2.运算律小学四年级课本下《运算律》知识点、由来、作用与意义解析**一、核心知识点****二、历史由来****三、…...

Git从入门到精通-第四章-更新仓库

目录 检查当前文件状态 追踪新文件 暂存已修改的文件&#xff08;git add作用总结&#xff09; 简化输出状态 忽略文件 查看已暂存和未暂存的修改 git diff 提交更新 git commit 跳过使用暂存区 前言&#xff1a;在工作区和Git仓库间设置暂存区的意义 1. ​精准控制…...

RPG8.增加武器

1.创建一个Actor的c类 2.创建武器WeaponBase的子类&#xff0c;给玩家的武器 3.进入WeaponBase&#xff0c;只留下构造函数&#xff0c;并且将bCanEventTick改为false&#xff0c;增加组件。 #pragma once#include "CoreMinimal.h" #include "GameFramework/Ac…...

力扣1128题解

记录 2525.5.4 题目&#xff1a; 思路&#xff1a; 先将dominoes[i]的二元全部变为前大后小的形式&#xff0c;再遍历该数组&#xff0c;用数组来记录。 代码&#xff1a; class Solution {public int numEquivDominoPairs(int[][] dominoes) {int [] [] cnt new int [10…...

微服务框架选型

1 Thrift&#xff0c; gRPC&#xff0c; Dubbo&#xff0c;Spring Cloud性能对比 指标ThriftgRPCDubboSpring Cloud序列化速度最快 (Binary)快 (Protobuf)中等 (Hessian2)慢 (JSON/XML)网络吞吐量最高 (无HTTP开销)高 (HTTP/2)中等 (TCP)低 (HTTP/1.1)延迟<1ms1-3ms2-5ms10…...

DeepSeek-Prover-V2模型原理速览

文章目录 prerequisite&#xff1a;Lean4研究亮点通过子目标分解实现递归证明搜索基于子目标的定理证明中的课程学习 统一非形式化推理和形式化证明通过合成数据实现冷启动以推理为导向的强化学习 DeepSeek-Prover-V2 的训练细节专家迭代监督式微调 快速使用REF DeepSeek-Prove…...

网络编程,使用select()进行简单服务端与客户端通信

这里在Ubuntu环境下演示 一般流程 服务端常用函数&#xff1a; socket()&#xff1a;创建一个新的套接字。bind()&#xff1a;将套接字与特定的IP地址和端口绑定。listen()&#xff1a;使套接字开始监听传入的连接请求。accept()&#xff1a;接受一个传入的连接请求&#xff…...

QT数据库实验

一、实验目的和要求 1、掌握Qt中掌握绘图工具和图形界面设计&#xff1b;绘制常见的图形。 2、熟悉Qt界面设计中常用的控件。 3、了解滚动条、滑动条、进度条、旋转按钮控件的用法。 二、实验内容 1、设计一个绘图软件&#xff0c;完成图像的绘制操作。 2、建立按钮的信号…...

【PyTorch完全指南】从深度学习原理到工业级实践

目录 🌟 前言技术背景与价值当前技术痛点解决方案概述目标读者说明🔍 一、技术原理剖析核心概念图解核心作用讲解关键技术模块技术选型对比🛠 二、实战演示环境配置要求核心代码实现1. 基础Tensor操作2. 神经网络构建3. 训练循环实现运行结果验证⚡ 三、性能对比测试方法…...

Spring AI 实战:第七章、Spring AI Advisor机制之记忆大师

引言:当AI的记性比金鱼还差 你:我叫张三,很高兴认识你AI:很高兴认识你,张三! 如果你有任何问题或者需要帮助,请随时告诉我你:我叫什么AI:抱歉,我无法知道你的名字。不过你可以告诉我一些关于你的信息,如果你愿意分享的话!AI的内心OS:爱谁谁,我反正不知道 如上图所…...

工业AI质检:从传统算法到多模态大模型应用

工业AI质检:从传统算法到多模态大模型应用 引言 在制造业质量控制领域,传统人工检测的漏检率高达15%-20%,而基于规则算法的视觉检测系统仅能处理已知缺陷类型。随着多模态大模型技术的突破,工业质检正进入"认知智能"新阶段——系统不仅能识别缺陷,更能理解工艺…...

STM32智能垃圾桶:四种控制模式实战开发

简介 从零到一打造企业级智能垃圾桶系统,实现按键、语音、红外、蓝牙多模式控制。本项目采用STM32F103C8T6作为主控芯片,通过模块化设计整合多种控制方式,确保系统稳定、高效且易于维护。文章将提供完整硬件连接方案、代码实现细节及企业级开发技术,帮助开发者掌握智能垃圾…...

Python语句入门:从基础到实践

Python作为一门简洁优雅的编程语言&#xff0c;其语句结构清晰易懂&#xff0c;非常适合初学者学习。本文将全面介绍Python中的各种基本语句&#xff0c;帮助编程新手快速掌握Python编程基础。语句是计算机执行程序的最小单位。 一、Python语句概述 Python程序由一系列语句组…...

Kubernetes(k8s)学习笔记(五)--部署Ingress实现域名访问和负载均衡

Ingress是基于nginx&#xff0c;通过在k8s中部署ingress&#xff0c;可实现域名访问和pod节点间的负载均衡。 下面是实现过程&#xff1a; 一.准备一个ingress-controller.yaml文件 apiVersion: v1 kind: Namespace metadata:name: ingress-nginxlabels:app.kubernetes.io/n…...

数据库MySQL学习——day8(复习与巩固基础知识)

文章目录 1. 数据库基础概念复习2. 常用SQL命令复习2.1 SELECT 查询数据2.2 INSERT 插入数据2.3 UPDATE 更新数据2.4 DELETE 删除数据 3. 表操作复习3.1 创建表3.2 修改表3.3 删除表 4. 实践任务4.1 创建样例数据库和表4.2 插入和更新数据4.3 使用WHERE、ORDER BY、LIMIT进行查…...

【ArcGIS微课1000例】0144:沿线或多边形要素添加折点,将曲线线段(贝塞尔、圆弧和椭圆弧)替换为线段。

文章目录 增密工具介绍举例1. 圆2. 椭圆3. 折线增密工具介绍 沿线或多边形要素添加折点。还可将曲线线段(贝塞尔、圆弧和椭圆弧)替换为线段。 原理图如下所示: 用法: 通过距离参数对直线段进行增密。利用距离、最大偏转角或最大偏移偏差参数,通过增密操作对曲线段进行简化…...

python中的模块/库

python中的模块/库 什么是库/模块&#xff0c;通俗来讲是用来干啥的&#xff1f; 模块/库就是一个/多个.py的一个文件。通常是用来定义一些通用的方法&#xff0c;避免代码冗余。怎么python中自带的这些模块和库&#xff1f; 使用import进行导入&#xff0c;之后其中的内容就可…...

全面掌握 Jetpack Compose 的 State 体系:核心用法与最佳实践

Jetpack Compose 中的 State 类型全面解析 Jetpack Compose 提供了多种 State 类型来管理 UI 状态。以下是主要的 State 类型及其使用场景&#xff1a; 基础 State 类型 1. mutableStateOf 最基本的可观察状态&#xff0c;用于简单值的变化跟踪&#xff1a; var count by …...

Pyhton类方法添加装饰器案例解析

from functools import wrapsdef keep_alive(func):"""装饰器&#xff1a;为方法自动维护长连接"""wraps(func)def wrapper(self, *args, **kwargs):if not self.conn:self.conn ConnectHandler(**self.device_params)self.conn.enable()return…...

58认知干货:创业经验分享及企业形式的汇总

机会永远都是留给有眼光、能发现机会的人,而不是留给有准备的人!往往机会就在身边,普罗大众却无法发现,而真正适合创业的人,天然具备这方面的能力。 当然后天的补足也未尝不可:“故常有欲以观其微,常无欲以观其妙。””引用《道德经》 读懂这句话自然便会拥有对商业和…...

n8n 快速入门2:构建自动化工作流

n8n 快速入门2:构建自动化工作流 什么是n8n?项目目标准备工作步骤一:创建新工作流步骤二:添加触发节点步骤三:配置NASA节点与凭证1. 添加NASA节点2. 设置NASA API凭证3. 使用表达式设置时间范围步骤四:添加If条件节点1. 创建条件分支2. 测试条件逻辑步骤五:配置输出节点…...

TimSort算法解析

文章目录 1. 核心数据结构1.1 TimSort类定义1.2 关键概念&#xff1a;Run 2. TimSort解决的具体问题分析2.1 处理现实世界中的数据特性2.2 提高排序稳定性2.3 优化归并排序的空间复杂度2.4 处理特殊情况的鲁棒性2.5 适应性能力与算法自调整2.6 优化合并操作效率 3. TimSort核心…...

CATIA高效工作指南——曲面设计篇(一)

引言 在工业设计领域&#xff0c;CATIA的曲面建模与线束展开功能是构建复杂产品的核心技术。本文整合了​​曲面封闭性检查​​、​​无参数曲面创建​​、​​缝合优化策略​​等核心知识点&#xff0c;结合实战案例与高阶技巧&#xff0c;为工程师提供系统化的解决方案。 一…...

PCB叠层设计方案

1叠层处理 在设计多层 PCB 电路板之前&#xff0c; 设计者需要首先根据电路的规模、 电路板的尺寸和电磁兼容&#xff08; EMC&#xff09;的要求来确定所采用的电路板结构&#xff0c; 也就是决定采用 4 层&#xff0c;6 层&#xff0c; 还是更多层数的电路板。 这就是设计多层…...

机器人编程基础---C语言中的控制语句

C语言中的控制语句 C语言中的控制语句条件语句if 语句switch 语句循环语句for 循环while 循环do-while 循环代码示例C语言中的控制语句 控制语句是编程中用于控制程序执行流程的语句。在C语言中,控制语句包括条件语句和循环语句,它们允许程序根据条件选择不同的执行路径或重…...

13.Excel:分列

一 分列的作用 将一个单元格中的内容拆分到两个或多个单元格当中。 二 如何使用 1.常规分列使用 注意&#xff1a;分列功能一次只能拆分一列。 长度一致或者数据间有分隔符。 补充&#xff1a;快速选择一列。 CTRL shift 向下箭头。 补充&#xff1a;中英文逗号不同。 可以先通…...

理解数学概念——幂律(power law)

在统计学中&#xff0c;幂律(power law)(即按照幂的规律)是指两个量之间的函数关系&#xff0c;其中一个量的相对变化会导致另一个量以与常量指数成正比的关系产生相对变化&#xff1a;一个量随着另一个量的幂而变化。(例如&#xff0c; &#xff0c;r 的变化导致s 按照幂 的…...