信号量基础入门:并发控制的核心概念
问题的复杂性产生的根本原因在于,如 2.2 节所述,共享变量的访问始终是“单向信息流”。也就是说,一个进程可以分配新值或检查当前值,但这种检查不会为其他进程留下任何痕迹。结果是,当一个进程想要对共享变量的当前值作出反应时,在检查和随后执行反应之间,该值可能已被其他进程更改。换句话说,现有的通信机制对于手头的问题来说是不充分的,我们需要寻找更合适的替代方案。
这种替代方案通过以下方式引入:
a) 在共享变量中引入特殊用途的整数,我们称之为“信号量(semaphores)”。
b) 在构成各个进程的动作集合中添加两种新的基本操作,我们分别称之为“P 操作”和“V 操作”。这些操作始终作用于信号量,并代表并发进程访问信号量的唯一方式。信号量本质上是非负整数。如果仅用于解决互斥(Mutual Exclusion)问题,则其值的范围甚至可以限制为“0”和“1”。荷兰物理学家兼计算机设计师 C.S. Scholten 博士证明了信号量在取更大值时具有广泛的应用价值。需要区分时,我们会将它们分别称为“二进制信号量(binary semaphores)”和“通用信号量(general semaphores)”。我接下来给出的 P 操作和 V 操作的定义不受这种区别的影响。
——Dijkstra 的笔记 EWD 123
引言
事实上,信号量是一个难以理解的概念。它是同步问题的核心,与互斥锁一起是最先学习的概念之一,但初次接触时往往难以理解。
通常,信号量可以用以下方式总结:
“信号量是一种通过 P 和 V 这两个特殊的原子操作来操作表示资源可用性的计数器,从而解决因共享资源并发访问而导致同步无法保证的问题的技术。”
但是,共享资源到底是什么?原子操作又是什么?资源的可用性、P 和 V 又是什么?
为了回答这些问题,我写下了这篇文章。
本文的目标是帮助理解并发编程的基础以及信号量的概念。
什么是共享资源?
当程序并行执行时,多个线程或进程同时访问的数据被称为“共享资源(shared resource)”。
- 示例:内存中的变量、文件句柄、网络端口、队列等。
共享资源具有状态(state)。如果同时对这个状态进行访问和修改,可能会引发意外错误。
用打印机比喻来理解共享资源
假设有一台打印机。想象一下,两个人同时尝试使用这台打印机时会发生什么:
- 如果 A 正在打印,而 B 在中途开始打印会怎样?
- 可能会导致打印中断、输出重叠,或者打印出空白页。
这表明对共享资源的并发访问会引起冲突。
为什么需要原子操作?
那么,如何解决这个问题呢?
核心在于,即使多个线程同时访问,也要确保状态的一致性,即保证“原子性(Atomicity)”。
例如,将变量 x
加 1 的操作 x = x + 1
实际上可以分解为以下三个步骤:
- 读取
x
的当前值。 - 将其加 1。
- 将结果写回
x
。
即使是这种看似简单的操作,如果有其他进程在中间介入,结果可能会被破坏。例如,两个线程同时执行 x = x + 1
时,最终结果可能只增加 1 而不是预期的 2,甚至可能出现更少的增量。
这种互相竞争修改值的情况导致了意想不到的状态,这种情况被称为竞态条件(Race Condition) 。
即使是“看起来像一行代码的操作”,实际上也可能分为多个步骤执行,因此需要一种防止中间介入的手段。
这就是原子操作 的作用。原子操作是不可分割的单位操作,在执行过程中不允许任何外部干预。
再次用打印机比喻来理解
- 当 A 向打印机发送打印请求时,只有在打印完全结束、失败或中止后,B 的请求才能开始处理。
- 如果在 A 打印过程中 B 插入并开始打印,可能会导致输出混合或部分丢失的错误。
- 因此,只有在“A 的打印状态”明确结束后,才能处理下一个请求(B),从而保证输出状态的一致性。
这就是原子性的要求条件。
在打印过程中,打印机的状态(State)应处于“使用中”的锁定(lock)状态,
只有在完全结束后才能进行下一个任务。
为了同时管理程序中的基于状态的资源 ,需要一个无法被中途打断的原子控制机制 。
好了,那么原子性是如何保证的呢?这就是我们今天的主题。
Dijkstra 的提议:什么是信号量?
特殊用途的整数(special-purpose integers)
正如之前打印机的例子所示,我们需要能够从外部明确控制和监控“正在使用中”的状态。然而,仅靠普通变量无法安全地管理这种状态。
原因如下:
- 任何人都可以读取和写入变量。
- 某个进程读取的值可能在下一刻被其他进程更改。
- 换句话说,在读取值并对其做出反应的时间间隔内,状态可能会发生变化,而这种变化不会被反映出来。
因此,现有的方式是一种容易中断的“检查-决定-执行”流程。
为了克服这种结构性限制,Edsger W. Dijkstra 提出了一个新的解决方案。
引入一种特殊用途的整数作为共享变量,我们称之为“信号量(semaphores)”。
——Dijkstra, EWD 123
什么是信号量?
信号量(semaphore)不仅仅是一个简单的整数。
它是一个外部访问受到控制的、具有特殊用途的状态值。
其核心在于:“禁止直接访问,只能通过两种操作(P/V)间接控制。”
在构成各个进程的动作集合中,添加两种新的基本操作,我们分别称之为“P 操作”和“V 操作”。这些操作始终作用于信号量,并代表并发进程访问信号量的唯一方式。
——Dijkstra, EWD 123
这个特殊的整数只能通过以下两个操作进行操作:
- P 操作 (Proberen,意为“测试”)
- V 操作 (Verhogen,意为“增加”)
这两个操作遵循以下规则:
操作 | 含义 | 效果 |
---|---|---|
P(s) | wait / acquire | 如果信号量值为正,则减 1 并通过;如果为 0,则等待。 |
V(s) | signal / release | 将信号量值增加 1。 |
这些操作始终以原子性 方式执行,即它们不会被任何中断或干扰打断。
这正是我们一直在寻找的“防止中途介入的机制”。
这就是信号量。
P/V 操作的定义
一个简单的实现如下:
// 信号量用整数值 s 表示
P(s): // waitwhile (s <= 0) wait;s = s - 1;V(s): // signals = s + 1; // 在此之后,如果有等待中的进程,需要唤醒它们
现代操作系统中,这一过程通过 futex、spinlock、sleep queue 等方式实现。
需要注意的是,在 P/V 操作伪代码中,s = s - 1
、s = s + 1
和 while (s <= 0) wait;
条件检查部分必须作为不可分割的原子操作 执行。
如果 P(s)
的 while (s <= 0) wait;
部分是通过持续占用 CPU 并反复检查条件是否满足的方式(即忙等待(busy-waiting 或 spin-waiting) ),那么这将非常低效地使用 CPU 资源。这是在浪费本可以用于其他有用任务的 CPU 时间。
因此,现代操作系统采用以下机制来更高效地处理这种“等待”过程,这些方法可以看作是现代异步处理的核心技术:
睡眠队列(Sleep Queue / Wait Queue)、上下文切换(Context Switching)、自旋锁(Spinlock)、以及 Futex(快速用户空间互斥锁) 。
这些方法的整体理论基础正是上述简单的操作。
总结一下,在现代操作系统中,信号量操作可以描述如下:
- 1. 基本的等待/唤醒: 使用睡眠队列 高效地挂起和唤醒进程(避免忙等待)。
- 2. 内部原子性保障: 在 P/V 操作短暂的执行期间,为了安全地修改信号量变量(如
s
)或睡眠队列,内核内部可能会使用自旋锁 等机制。 - 3. 性能优化(尤其是 Linux): 利用Futex ,当没有资源竞争时在用户空间快速处理,只有在发生竞争时才使用内核的睡眠队列功能,从而减少系统调用开销。
二进制信号量 vs 通用信号量
区分 | 含义 | 使用场景 |
---|---|---|
二进制信号量 | 值:0 或 1 | 等同于互斥锁(Mutex) |
通用信号量 | 值:0 或更大 | 有限资源(例如:数据库连接池) |
-
C.S. Scholten 的通用信号量概念扩展。
-
与互斥锁的区别: 拥有权限的概念 vs 状态驱动模型
让我们回到打印机的例子,使用信号量控制打印机。
在打印机示例中应用二进制信号量的过程如下:
- 用一个初始值为
s = 1
的信号量表示打印机的状态。 - 用户 A 调用
P(s)
,将s
减为0
并开始打印。 - 在用户 A 打印过程中,用户 B 调用
P(s)
,但由于s <= 0
,用户 B 进入等待状态。 - 用户 A 完成打印后调用
V(s)
,使s = 1
,用户 B 随即可以开始打印。
通过这种方式,信号量将资源的“状态”抽象为数字,并通过原子操作改变该数值,从而实现对并发的控制。
前面提到的二进制信号量 适用于办公室只有一台打印机的情况(互斥访问)。
s=1
表示“打印机可用”,s=0
表示“打印机正在使用”。
但是,如果办公室有多个相同性能的打印机(例如:3 台)该怎么办呢?
在这种情况下,虽然允许多个人同时使用打印机,但必须确保使用的打印机数量不会超过可用的数量。
这正是**通用信号量(General Semaphore)或 计数信号量(Counting Semaphore)**发挥作用的时候。
通用信号量 s
是一个非负整数值,用于表示可用资源的数量。
使用通用信号量控制 3 台打印机的示例
-
初始状态:
- 办公室有 3 台打印机,因此信号量
s
的初始值设置为3
(s = 3
)。 - 这表示“当前有 3 台可用的打印机”。
- 办公室有 3 台打印机,因此信号量
-
用户 A 请求使用打印机(执行
P(s)
操作):- 调用
P(s)
。 - 当前
s
的值(3)大于 0,因此将s
减 1(s = 2
)。 - 用户 A 分配到一台打印机并开始打印。(现在可用的打印机数量为 2)
- 调用
-
用户 B 请求使用打印机(执行
P(s)
操作):- 调用
P(s)
。 - 当前
s
的值(2)大于 0,因此将s
减 1(s = 1
)。 - 用户 B 也分配到一台打印机并开始打印。(现在可用的打印机数量为 1)
- 调用
-
用户 C 请求使用打印机(执行
P(s)
操作):- 调用
P(s)
。 - 当前
s
的值(1)大于 0,因此将s
减 1(s = 0
)。 - 用户 C 分配到一台打印机并开始打印。(现在可用的打印机数量为 0)
- 调用
-
用户 D 请求使用打印机(执行
P(s)
操作):- 调用
P(s)
。 - 当前
s
的值(0)小于或等于 0,因此用户 D 会在P(s)
操作中的while (s <= 0) wait;
条件下进入等待状态 ,直到有打印机可用。
- 调用
-
用户 A 打印完成并归还打印机(执行
V(s)
操作):- 用户 A 完成打印后调用
V(s)
。 - 将
s
增加 1(s = 1
)。(现在有 1 台打印机可用) V(s)
操作完成后,之前在P(s)
操作中等待的用户 D 被唤醒,并重新检查s
的值。由于s
现在为 1,用户 D 将s
设置为 0 并开始使用打印机。
- 用户 A 完成打印后调用
通用信号量的核心作用:
如上所述,通用信号量不仅仅是一个简单的二进制“锁定/解锁”机制,它还可以精确管理有限资源池的并发访问 ,并准确跟踪可用资源的数量 。
结语
信号量仍然是内核级同步的核心工具,同时也是基于状态的访问模型的典型代表。
信号量看似只是一个简单的整数,
但它却是系统中用于准确表示资源状态 、
安全控制资源 、以及以可预测的方式共享资源的唯一抽象手段 。
我们必须牢记,在这个小小的整数背后,
承载着无数进程的秩序、冲突避免和系统稳定性 。
相关文章:
信号量基础入门:并发控制的核心概念
问题的复杂性产生的根本原因在于,如 2.2 节所述,共享变量的访问始终是“单向信息流”。也就是说,一个进程可以分配新值或检查当前值,但这种检查不会为其他进程留下任何痕迹。结果是,当一个进程想要对共享变量的当前值作…...
物联网之使用Vertx实现HTTP/WebSocket最佳实践
小伙伴们,你们好呀,我是老寇,跟我一起学习使用Vertx实现HTTP-Server和WebSocket-Server 实现Http/WebSocket【响应式】 Vertx-Web地址 实现过程 查看源码 代码比较简单,懒得讲解啦 代码比较简单,懒得讲解啦 代码…...
【神经网络与深度学习】GAN 生成对抗训练模型在实际训练中很容易判别器收敛,生成器发散
引言部分 在深度学习领域,生成对抗网络(GAN)是一种强大的数据生成方法,它通过生成器(G)和判别器(D)之间的博弈来不断优化模型。然而,在实际训练过程中,GAN 往…...
使用 NGINX 的 `ngx_http_secure_link_module` 模块保护资源链接
一、模块简介 版本:自 NGINX 0.7.18 起引入 功能: 签名校验:对请求 URI 中的签名进行校验,保证链接未经篡改。时效控制:根据请求中携带的过期时间,判断链接是否仍在有效期。 启用方式:编译 NG…...
5月19日day30打卡
模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 作业:自己新建几个不同路径文件尝试下如何导入 一、导入官方库 …...
NW860NW894美光闪存颗粒NX770NX789
在数字化浪潮席卷全球的当下,数据存储技术的革新正以惊人的速度推动着硬件性能的边界。美光科技作为半导体存储领域的领军者,其NW860、NW894、NX770、NX789系列闪存颗粒凭借前沿架构与精密工艺,成为高性能存储解决方案的核心载体。本文将深入…...
高性能锁机制 CAS:Java 并发编程中的深度剖析
引言 在并发编程领域,i操作的非线程安全性是开发者们熟知的问题。这一现象根源在于i并非原子操作,其内部执行过程包含读取、修改和写入三个步骤,在多线程环境下极易因线程切换导致数据竞争与不一致,这与我们此前探讨的多线程常见问…...
leetcode 每日一题 1931. 用三种不同颜色为网格涂色
题目 1931. 用三种不同颜色为网格涂色 思路 先获取列表,上下左右的所有情况。解决一维的问题 然后所有一维的问题暴力循环。已知一个一维的解,可以对应其他一维解的列表(用于记忆化搜索) 然后使用递归,进行累加 代…...
解决Windows磁盘管理中因夹卷导致的无法分区问题
解决Windows磁盘管理中因夹卷导致的无法分区问题 在现代计算机管理中,磁盘分区是一个常见且重要的操作。无论是为了优化存储空间,还是为了实现多系统安装,合理的磁盘分区都是必不可少的。然而,许多用户在使用Windows磁盘管理工具…...
龙虎榜——20250519
上证指数缩量收十字星,个股涨多跌少,这周反弹的概率比较大。 深证指数缩量调整,临近反弹,个股表现更好。 2025年5月19日龙虎榜行业方向分析 化工(新能源材料国产替代) • 代表个股:红宝丽、…...
Python在自动驾驶数据清洗中的应用
Python在自动驾驶数据清洗中的应用 在自动驾驶领域,数据是算法的燃料。高质量的数据意味着更精准的模型,更稳定的驾驶体验。然而,原始数据通常充满噪声、缺失值、不一致格式,甚至有异常点,这些都会严重影响自动驾驶系统的可靠性。因此,数据清洗是一道绕不开的关卡。 一…...
腾讯云Mysql实现远程链接
1.SQL语句:CREATE USER remote_user% IDENTIFIED BY YourPassword; GRANT ALL PRIVILEGES ON *.* TO remote_user%; FLUSH PRIVILEGES; 2.设置入站规则 3.设置安全组 4.效果...
大模型(2)——提示工程(Prompt Engineering)
文章目录 一、提示工程的核心概念为什么需要提示工程? 二、提示设计的基本原则三、实用提示工程技巧1. 角色设定法2. 示例引导法(Few-Shot Learning)3. 分阶段提问4. 负面约束5. 温度(Temperature)控制 四、不同任务类…...
深入Java G1 GC调优:如何解决高延迟与吞吐量瓶颈
引言 Java的垃圾回收(GC)机制是JVM性能的核心,但即使是最先进的G1(Garbage-First)收集器,在复杂场景下仍可能引发长时间停顿(Stop-The-World, STW)或吞吐量骤降。许多开发者虽然熟…...
DAPO:用于指令微调的直接偏好优化解读
一、背景与动机:从RLHF到DPO,再到DAPO 大型语言模型(LLM)经过海量无监督预训练后,往往需要对齐人类偏好或遵循指令的微调,使模型的回答更符合人类期望。这一过程通常通过人类反馈强化学习(RLHF)来实现。例如OpenAI的ChatGPT就使用了RLHF:先让人工标注对模型输出进行偏…...
vue2、vue3项目打包生成txt文件-自动记录打包日期:git版本、当前分支、提交人姓名、提交日期、提交描述等信息 和 前端项目的版本号json文件
vue2 打包生成text文件 和 前端项目的版本号json文件 项目打包生成txt文件-自动记录git版本、当前分支、提交人姓名、提交日期、提交描述等信息生成版本号json文件-自动记录当前版本号、打包时间等信息新建branch-version-webpack-plugin.js文件 // 同步子进程 const execSyn…...
iOS解码实现
import Foundation import VideoToolboxclass KFVideoDecoderInputPacket {var sampleBuffer: CMSampleBuffer? }class KFVideoDecoder {// MARK: - 常量private let kDecoderRetrySessionMaxCount 5private let kDecoderDecodeFrameFailedMaxCount 20// MARK: - 回调var pi…...
Windows中PDF TXT Excel Word PPT等Office文件在预览窗格无法预览的终级解决方法大全
Windows中PDF TXT Excel Word PPT等Office文件在预览窗格无法预览的终级解决方法大全 参考链接: https://zhuanlan.zhihu.com/p/454259765...
在Excel中使用函数公式时,常见错误对应不同的典型问题
在Excel中使用函数公式时,常见错误对应不同的典型问题 1. #DIV/0!(除以零错误)2. #N/A(值不可用)3. #NAME?(名称错误)4. #NULL!(空交集错误)5. #NUM!(数值错…...
Excel
1.快捷键 CtrlE 快速填充 CtrlQ 快速分析 CtrlEnter 原位填充 Tab 横向移动到下一个单元格 Enter 移动到下一行起始位置对应单元格 Shift 返回上一个单元格 0空格分数 显示分数 1.if if(condition,true,false)if(A1>10,"true","fa…...
Rust 学习笔记:错误处理
Rust 学习笔记:错误处理 Rust 学习笔记:错误处理不可恢复的错误带有结果的可恢复错误匹配不同的错误出现错误时 panic 的快捷方式:unwrap 和 expect传播错误传播错误的快捷方式:? 操作符哪里可以使用 ? 操作符 panic or not pan…...
【Linux】系统指令与开发全栈(vim、ssh、gcc)
【Linux】系统指令与开发全栈(vim、ssh、gcc) 一、Linux 系统指令大全 1、文件与目录管理 基础操作 指令参数说明典型用例注意事项cd~ 家目录,- 返回上级,.. 上级目录cd ~/Documents 进入文档目录无目录权限时会报错ls-l 详情&am…...
用 CodeBuddy 搭建「MiniGoal 小目标打卡器」:一次流畅的 UniApp 开发体验
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 在日常生活中,我们总是希望能够坚持一些小习惯,比如每天锻炼十分钟、读一页书、早睡十分…...
前端(vue)学习笔记(CLASS 6):路由进阶
1、路由的封装抽离 将之前写在main.js文件中的路由配置与规则抽离出来,放置在router/index.js文件中,再将其导入回main.js文件中,即可实现路由的封装抽离 例如 //index.js import { createMemoryHistory, createRouter } from vue-routerim…...
ubuntu 安装 Redis新版Redis 7.x
以下是在Ubuntu系统中安装Redis的详细指南, 一、官方APT源安装 sudo apt install redis-server -y 默认安装最新APT源版本(Ubuntu 22.04通常为Redis 6.x) 服务自动启动,配置文件路径:/etc/redis/redis.conf验证安装 …...
Httphelper: Http请求webapi小记
文章目录 1、HttpHelper.cs Framework4.812、HttpHelper.cs NET83、JsonHelper.cs Framework4.814、JsonHelper.cs NET85、uniapp request.js 访问WEBAPI 每次查找、测试都比较费事,记录一下把 1、HttpHelper.cs Framework4.81 using System; using System.IO; usi…...
【Linux】进程控制(进程创建、进程终止、进程等待、进程替换)
目录 一、进程创建 1、fork函数 2、页表权限 二、进程终止 1、main函数返回值(退出码) 2、常见错误码及其对应的错误描述: 将错误退出码转化为错误描述的方法: 3、进程退出的三种场景 4、由上我们可以知道: 5…...
java+selenium专题->启动浏览器下篇
1.简介 上一篇文章,我们已经在搭建的java项目环境中实践了,今天就在基于maven项目的环境中演示一下。 2.eclipse中新建maven项目 1.依次点击eclipse的file - new - other ,如下图所示: 2.在搜索框输入关键字“maven”ÿ…...
sqlserver 循环删除1000行
在SQL Server中,如果你想循环删除1000行数据,有几种方法可以实现,但值得注意的是,频繁使用循环删除操作可能会对数据库性能造成影响,尤其是在处理大量数据时。下面介绍几种方法,并讨论它们的优缺点。 方法…...
亚信电子与联发科技携手打造AIoT新未来
[台湾新竹讯, 2025年5月19日] 智能物联网(AIoT)融合人工智能与物联网技术,通过边缘AI的实时数据分析及设备智能联网能力,加速智能物联网创新应用的蓬勃发展。为满足AIoT产业对多网络端口的应用需求,全球半导体公司【联…...
【成品设计】基于STM32的人体健康监测系统
《基于STM32的人体健康监测系统》 Ps:有4个版本。 V1硬件设计: 主控:STM32F103C8T6:作为系统主控芯片。 血氧心率传感器:用于采集当前心率、血氧值。 温湿度传感器:用于采集当前环境温湿度。 有源低电平触发蜂鸣器&…...
【MySQL进阶】了解linux操作系统下mysql的配置文件和常用选项
前言 🌟🌟本期讲解关于linux下mysql配置选项的详细介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么…...
LeetCode 219.存在重复元素 II
目录 题目: 题目描述: 题目链接: 思路: 核心思路: 思路详解: 代码: C代码: Java代码: 题目: 题目描述: 题目链接: 219. 存…...
解释:神经网络
在过去的10年里,表现最好的artificial-intelligence系统——比如智能手机上的语音识别器或谷歌最新的自动翻译——都是由一种叫做“深度学习”的技术产生的 深度学习实际上是一种被称为神经网络的人工智能方法的新名称,这种方法已经流行了70多年。1944年…...
Java 泛型详解
在 Java 的类型系统中,泛型(Generics) 是一个非常重要的特性。它让我们能够编写更通用、更安全的代码,尤其是在处理集合类(如 List、Map 等)时,泛型的使用可以大大减少类型转换的麻烦࿰…...
React集成百度【JSAPI Three】教程(001):快速入门
文章目录 1、快速入门1.1 创建react项目1.2 安装与配置1.3 静态资源配置1.4 配置百度地图AK1.5 第一个DEMO1、快速入门 JSAPI Three版本是一套基于Three.js的三维数字孪生版本地图服务引擎,一套引擎即可支持2D、2.5D、3D全能力的地理投影与数据源加载,帮助开发者轻松搞定平面…...
WPF中资源(Resource)与嵌入的资源(Embedded Resource)的区别及使用场景详解
🌟 开发WPF项目时图片、SVG、配置文件等到底该设置为哪种资源?如何正确读取、跨程序集访问?一篇文章全解答。 在使用 WPF 进行项目开发时,很多开发者在设置文件“生成操作(Build Action)”时,常常会在“资源(Resource)”和“嵌入的资源(Embedded Resource)”之间感…...
如何在 Windows 11 或 10 上安装 Fliqlo 时钟屏保
了解如何在 Windows 11 或 10 上安装 Fliqlo,为您的 PC 或笔记本电脑屏幕添加一个翻转时钟屏保以显示时间。 Fliqlo 是一款适用于 Windows 和 macOS 平台的免费时钟屏保。它也适用于移动设备,但仅限于 iPhone 和 iPad。Fliqlo 的主要功能是在用户不活动时在 PC 或笔记本电脑…...
【STM32】ST-Link V2.1制作
一、下载烧写工具及程序 下载器制作(ST-Link V2.1) 链接: 提取码:6666https://pan.baidu.com/s/1n0RYNDEw5mBT_CsTFoqrIg?pwd6666 二、安装STM32 CubeProgrammer 双击安装包,点击Next 继续点击Next 选择安装路径,再…...
day30python打卡
知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 作业:自己新建几个不同路径文件尝试下如何导入 一、导入官方库 我们复盘下学习py…...
AI大语言模型评测体系演进与未来展望
随着人工智能技术的飞速发展,大语言模型(LLMs)已成为自然语言处理领域的核心研究方向。2025年最新行业报告显示,当前主流模型的评测体系已从单一任务评估转向多维度、全链路的能力剖析。例如,《全球首个大语言模型意识水平”识商”白盒DIKWP测评报告》通过数据、信息、知识…...
用Python将 PDF 中的表格提取为 Excel/CSV
*用Python将 PDF 中的表格提取为 Excel/CSV,*支持文本型 PDF 和 扫描件/图片型 PDF(需 OCR 识别)。程序包含以下功能: 1.自动检测 PDF 类型(文本 or 扫描件) 2.提取表格数据并保存为 Excel/CSV 3.处理多页…...
【工具】ncdu工具安装与使用指南:高效管理Linux磁盘空间
磁盘空间管理是Linux系统维护中的关键任务。当系统提示"磁盘空间不足"时,快速找出占用大量空间的文件和目录变得尤为重要。虽然传统的du命令可以完成这项工作,但其输出往往难以阅读和分析。本文介绍的ncdu(NCurses Disk Usage&…...
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Progress Steps (步骤条)
📅 我们继续 50 个小项目挑战!—— Progress Steps 组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/ ✨ 组件目标 展示一个多步骤的进度条,指示当前所…...
数据分析—Excel数据清洗函数
在做数据分析的过程中,我们从数据库或者网页中获取的外部数据,通常是无法直接使用进行数据分析的。数据经常会有尾随的空格、奇奇怪怪的前缀和非打印字符等等问题,那么我们就需要先对数据进行清洗。下面介绍一些在数据清洗过程中常用的Excel函…...
CEF源码历史版本编译避坑指南
cef编译,网上查到的相关资料大多是官网上自动化编译的翻版,可能较新的版本按照那个步骤编译是没问题的。但是,对于历史版本的编译就会遇到各种坑。步骤大同小异,所以不再赘述,重点记录下针对历史版本编译要注意的点&am…...
看之前熟悉双亲委派加载机制,看之后了解双亲委派加载机制
今天面试被拷打双亲委派加载机制了,麻了。 首先要介绍双亲委派加载机制,就需要先搞明白啥是Java的类加载机制。 一.介绍 Java虚拟机(JVM)作为Java语言的核心运行环境,承担着将Java字节码转换为机器码并执行的重任。…...
std::ranges::views::stride 和 std::ranges::stride_view
std::ranges::views::stride 是 C23 中引入的一个范围适配器,用于创建一个视图,该视图只包含原始范围中每隔 N 个元素的元素(即步长为 N 的元素)。 基本概念 std::ranges::stride_view 是一个范围适配器,接受一个输…...
IBM Spectrum Scale (GPFS) 日常运维命令大全
目录 1. 集群管理命令 1.1 集群启动与停止 1.2 节点管理 1.3 集群配置查看与修改 2. 文件系统管理 2.1 文件系统创建与删除 2.2 文件系统挂载与卸载 2.3 文件系统属性修改 3. 存储池与磁盘管理 3.1 存储池管理 3.2 物理磁盘管理 3.3 磁盘故障处理 4. 性能监控与调优…...
IDE 使用技巧与插件推荐
在现代软件开发中,集成开发环境(IDE)不仅是代码编辑器,更是提升开发效率和代码质量的强大平台。本文将从基础使用技巧、高级功能、插件生态、定制化配置及实战案例五大方面,帮助你全面掌握 IDE,提高编程体验…...