linux inotify 资源详解
Linux 的 inotify
是一个强大的文件系统监控机制,允许应用程序实时监听文件和目录的变化。这对于需要响应文件系统事件的应用(如配置热加载、备份工具、文件同步服务等)至关重要。以下是对 inotify
资源的深度解析:
一、核心概念
1. 基本组件
资源类型 | 作用 | 默认限制(内核 5.x) |
---|---|---|
instances | 每个进程可创建的 inotify 实例数量(每个实例对应一个文件描述符 fd) | fs.inotify.max_user_instances = 128 |
watches | 每个实例可监控的文件/目录数量(即监视点总数) | fs.inotify.max_user_watches = 8192 |
queues | 每个实例的事件队列大小(未处理事件上限) | fs.inotify.max_queued_events = 16384 |
2. 关键系统调用
inotify_init()
/inotify_init1()
:创建 inotify 实例。inotify_add_watch()
:添加监控路径,指定关注的事件类型(如IN_MODIFY
、IN_CREATE
)。inotify_rm_watch()
:移除监控路径。read()
:从事件队列读取事件数据。
3. 常见事件类型
事件类型 | 描述 |
---|---|
IN_ACCESS | 文件被访问(如 read ) |
IN_MODIFY | 文件内容被修改(如 write ) |
IN_ATTRIB | 文件属性被修改(如权限、时间戳) |
IN_CLOSE_WRITE | 可写文件被关闭 |
IN_CLOSE_NOWRITE | 不可写文件被关闭 |
IN_OPEN | 文件被打开 |
IN_MOVED_FROM | 文件移出监控目录 |
IN_MOVED_TO | 文件移入监控目录 |
IN_CREATE | 文件 / 目录在监控目录内被创建 |
IN_DELETE | 文件 / 目录在监控目录内被删除 |
IN_DELETE_SELF | 被监控的文件 / 目录本身被删除 |
IN_MOVE_SELF | 被监控的文件 / 目录被移动 |
二、资源限制与调优
1. 系统级限制参数
# 查看当前限制
cat /proc/sys/fs/inotify/max_user_watches # 每个用户可创建的最大 watch 数量(默认 8192)
cat /proc/sys/fs/inotify/max_user_instances # 每个用户可创建的最大 inotify 实例数(默认 128)
cat /proc/sys/fs/inotify/max_queued_events # 事件队列的最大容量(默认 16384)# 临时调整(重启后失效)
sysctl -w fs.inotify.max_user_watches=524288# 永久调整(/etc/sysctl.conf)
echo "fs.inotify.max_user_watches=524288" >> /etc/sysctl.conf
sysctl -p
2. 性能考量
- 内存占用:每个 watch 约占用 100-200 字节内存。
- CPU 开销:频繁的文件系统操作会触发大量事件,增加内核负担。
- 磁盘 I/O:监控可能导致额外的磁盘访问(如读取文件属性)。
3. 优化建议
- 避免递归监控:递归监控会为每个子目录创建 watch,使用
find . | wc -l
估算潜在 watch 数量。 - 使用文件过滤:通过掩码(如
IN_CREATE | IN_MODIFY
)仅关注必要的事件类型。 - 限制监控深度:对于大型目录,可设置监控深度或仅监控特定子目录。
- 异步处理事件:使用线程池或协程处理事件,避免阻塞主线程。
三、与容器的关系
1. 容器内的 inotify 限制
- 共享宿主机限制:容器默认共享宿主机的
max_user_watches
,可能导致资源竞争。 - 容器重启丢失监控:容器重启后,原有的 inotify 实例和 watch 会丢失,需重新初始化。
2. Kubernetes 中的应用
- ConfigMap/Secret 热更新:Kubernetes 通过 inotify 监控挂载的配置文件变化,触发应用重新加载。
- Downward API:通过 inotify 实现 Pod 元数据变化的实时感知。
四、故障排查
1. 常见错误场景
- ENOSPC(No space left on device):watch 数量超过
max_user_watches
。# 增加限制 sysctl -w fs.inotify.max_user_watches=524288
- 事件丢失:事件队列满(超过
max_queued_events
),需增大队列或优化事件处理逻辑。 - CPU 使用率高:频繁的文件系统操作触发大量事件,需优化监控范围或应用逻辑。
-
EMFILE
错误(Too many open files):进程的 inotify 实例数超过max_user_instances
限制。解决方案:1)增加max_user_instances;2)
优化程序逻辑,复用 inotify 实例。
2. 监控工具
- lsof:查看 inotify 实例和 watch 信息。
lsof -p <PID> | grep inotify # 查看特定进程的 inotify 使用情况
- sysdig:实时监控 inotify 系统调用。
sysdig -c spy_users inotify # 监控所有用户的 inotify 活动
- perf:分析 inotify 相关的性能瓶颈。
perf record -g -a -e syscalls:sys_enter_inotify_add_watch perf report
五、应用场景与工具
1. 常用工具
-
inotifywait
(来自inotify-tools
包):监控文件事件并触发动作。inotifywait -m -r /path/to/dir
-
watchman
:Facebook 开发的监控工具,优化大规模文件监听。 -
fswatch
:跨平台文件监控工具,支持 inotify。
2. 开发场景
-
前端热重载:Webpack 或 Vite 使用 inotify 监听文件变化。
-
日志监控:实时追踪日志文件追加事件(如
tail -f
)。
六、高级用法与替代方案
1. 结合 epoll 实现高效事件处理
// 示例:使用 epoll 监听 inotify 事件
int epfd = epoll_create(1);
struct epoll_event ev, events[10];// 将 inotify 实例添加到 epoll
ev.events = EPOLLIN | EPOLLET; // 使用边缘触发模式
ev.data.fd = fd; // fd 是 inotify 实例的文件描述符
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);// 事件循环
while (1) {int nfds = epoll_wait(epfd, events, 10, -1);for (int i = 0; i < nfds; i++) {if (events[i].data.fd == fd) {// 处理 inotify 事件read_inotify_events(fd);}}
}
2. 替代方案
- 轮询(Polling):定期检查文件状态,适用于低频率变化的场景。
- dnotify:老版 Linux 文件系统监控机制,功能有限,已被 inotify 取代。
- fanotify:更底层的文件系统监控,适合系统级监控(如病毒扫描)。
- fswatch:跨平台文件监控工具,基于 inotify(Linux)、kqueue(macOS)等实现。
七、最佳实践
- 按需监控:仅监控必要的路径和事件类型。
- 限制规模:避免监控
/
或大型目录,设置合理的max_user_watches
。 - 批量处理:对短时间内的重复事件(如文件连续修改)进行合并处理。
- 资源监控:定期检查 inotify 使用情况,设置告警阈值。
- 优雅处理错误:当达到系统限制时,应用应能降级处理或通知管理员。
八、性能优化建议
-
减少递归监控
避免无差别监控整个目录树,改用精确路径。 -
合并事件处理
对高频事件(如MODIFY
)进行防抖处理。 -
限制监控深度
使用--exclude
或--include
过滤无关文件。 -
选择高效工具
对大规模监控场景,优先使用watchman
或内核级方案(如fanotify
)。
九、统计各进程占用的 inotify 信息
1. 统计各进程占用的 inotify watches 数量
要统计 Linux 系统中各进程占用的 inotify watches 数量,可以通过以下几种方法实现:
方法一:使用 lsof
命令(简单直接)
lsof | grep inotify | awk '{print $2, $1}' | sort -n | uniq -c | sort -nr
输出示例:
123 12345 chrome45 67890 code20 23456 docker
解析:
lsof | grep inotify
:列出所有 inotify 文件描述符。awk '{print $2, $1}'
:提取 PID 和进程名。sort -n | uniq -c
:统计每个 PID 的出现次数(即 watches 数量)。sort -nr
:按 watches 数量降序排列。
方法二:遍历 /proc
目录(更精确)
#!/bin/bashecho "WATCHES PID COMMAND"
echo "------- --- -------"for pid_dir in /proc/[0-9]*/; dopid=$(basename "$pid_dir")inotify_fd_count=$(ls -1 "$pid_dir/fd" 2>/dev/null | \xargs -I{} readlink -f "$pid_dir/fd/{}" 2>/dev/null | \grep -c 'anon_inode:inotify')if [ "$inotify_fd_count" -gt 0 ]; thencomm=$(cat "$pid_dir/comm" 2>/dev/null || echo "unknown")echo "$inotify_fd_count $pid $comm"fi
done | sort -rnk1
输出示例:
WATCHES PID COMMAND
------- --- -------1234 12345 chrome456 67890 code234 23456 docker
方法三:使用 pysysinfo
脚本(更详细)
# 安装 pysysinfo
pip install pysysinfo# 统计 inotify watches
pysysinfo --inotify | sort -k2 -nr
输出示例:
PID NAME INOTIFY_WATCHES
12345 chrome 1234
67890 code 456
23456 docker 234
方法四:自定义监控脚本(实时监控)
#!/usr/bin/env python3
import os
import re
from collections import defaultdictdef count_inotify_watches():watches = defaultdict(int)for pid in os.listdir('/proc'):if not pid.isdigit():continuetry:with open(f'/proc/{pid}/fdinfo/{fd}') as f:fdinfo = f.read()if 'inotify' in fdinfo:watches[pid] += 1except (PermissionError, FileNotFoundError):continuereturn watchesdef get_process_name(pid):try:with open(f'/proc/{pid}/comm') as f:return f.read().strip()except (PermissionError, FileNotFoundError):return 'unknown'if __name__ == '__main__':watches = count_inotify_watches()print("PID\tWATCHES\tPROCESS")for pid, count in sorted(watches.items(), key=lambda x: x[1], reverse=True):print(f"{pid}\t{count}\t{get_process_name(pid)}")
高占用进程排查建议
- 识别异常进程:找出 watches 数量远高于其他进程的应用(如 Chrome、VS Code 等可能有较高占用)。
- 优化监控逻辑:对于开发中的应用,检查是否存在递归监控整个目录的情况。
- 调整系统限制:如确实需要大量 watches,可增加
max_user_watches
:sysctl -w fs.inotify.max_user_watches=524288 # 临时调整 echo "fs.inotify.max_user_watches=524288" >> /etc/sysctl.conf # 永久调整
- 监控工具:结合 Prometheus 和 Grafana 持续监控 inotify 使用情况。
注意事项
- 权限问题:需要 root 权限才能查看所有进程的 fdinfo。
- 性能开销:遍历
/proc
目录会有一定性能开销,建议仅在必要时执行。 - 容器环境:在容器内可能只能看到当前容器的 inotify 使用情况。。
2. 统计各进程占用的 inotify event 数量
要统计 Linux 系统中各进程占用的 inotify events 数量(而非 watches 数量),可以通过以下方法实现。需要注意的是,events 是动态产生的,统计难度较大,以下方案各有侧重:
方法一:使用 perf
监控 inotify 系统调用(实时统计)
# 统计一段时间内的 inotify_add_watch 和 inotify_rm_watch 调用次数
perf stat -e syscalls:sys_enter_inotify_add_watch,syscalls:sys_enter_inotify_rm_watch -a sleep 10
输出示例:
Performance counter stats for 'system wide':12,345 syscalls:sys_enter_inotify_add_watch4,567 syscalls:sys_enter_inotify_rm_watch10.001000 seconds time elapsed
方法二:通过 sysdig
追踪事件(实时监控)
# 统计各进程产生的 inotify 事件数量
sysdig -c spy_users inotify | grep -v ^# | awk '{print $1, $2, $3}' | sort | uniq -c | sort -nr
输出示例:
12345 chrome IN_MODIFY4567 code IN_ACCESS2345 docker IN_CREATE
方法三:解析内核日志(历史统计)
如果内核配置了 CONFIG_DEBUG_FS
,可以通过 debugfs 查看 inotify 统计信息:
# 挂载 debugfs(如未挂载)
mount -t debugfs none /sys/kernel/debug# 查看 inotify 事件统计
cat /sys/kernel/debug/inotify/stats
输出示例:
total_events: 1234567
events_by_type:IN_ACCESS: 123456IN_MODIFY: 456789IN_CREATE: 234567...
方法四:自定义监控脚本(动态追踪)
以下 Python 脚本通过 bcc
(BPF Compiler Collection)动态追踪 inotify 事件:
#!/usr/bin/env python3
from bcc import BPF# BPF 程序
bpf_text = """
#include <linux/inotify.h>// 存储事件计数
struct event_count {u64 count;
};BPF_HASH(event_counts, u32, struct event_count); // 按 PID 计数
BPF_HASH(type_counts, u32, struct event_count); // 按事件类型计数// 捕获 inotify 事件
int trace_inotify_event(struct ptrace_regs *ctx) {u32 pid = bpf_get_current_pid_tgid() >> 32;struct inotify_event *event = (struct inotify_event *)PT_REGS_PARM2(ctx);// 更新 PID 事件计数struct event_count *pid_count = event_counts.lookup(&pid);if (pid_count) {pid_count->count++;} else {struct event_count init = {1};event_counts.update(&pid, &init);}// 更新事件类型计数u32 type = event->mask;struct event_count *type_count = type_counts.lookup(&type);if (type_count) {type_count->count++;} else {struct event_count init = {1};type_counts.update(&type, &init);}return 0;
}
"""# 加载 BPF 程序
b = BPF(text=bpf_text)
b.attach_kprobe(event="sys_inotify_read", fn_name="trace_inotify_event")# 打印表头
print("PID\tEVENTS")# 定期输出统计结果
try:while True:for k, v in b["event_counts"].items():print(f"{k.value}\t{v.count}")b["event_counts"].clear()b["type_counts"].clear()print("---")sleep(1)
except KeyboardInterrupt:exit()
输出示例:
PID EVENTS
12345 123
67890 45
23456 78
---
方法五:结合 Prometheus + Grafana(长期监控)
1)安装 node_exporter
并启用 inotify 监控:
# 启动 node_exporter 时添加 inotify 收集器
./node_exporter --collector.inotify
2)配置 Prometheus 抓取指标:
scrape_configs:- job_name: 'node'static_configs:- targets: ['localhost:9100']
3)在 Grafana 中创建仪表盘:
- 指标:
node_inotify_watches
(按 PID 分组) - 图表:时序图或表格,展示各进程的 inotify 事件趋势
注意事项
- 性能开销:动态追踪 inotify 事件会带来一定性能开销,尤其是高频率事件场景。
- 权限要求:运行
perf
、sysdig
或 BPF 程序需要 root 权限。 - 事件定义:区分 watch 数量(静态配置)和 event 数量(动态产生)。
- 容器环境:容器内可能无法直接访问宿主机的 inotify 统计信息。
3. 统计各进程占用的 inotify instances 数量
要统计 Linux 系统中各进程占用的 inotify instances 数量(即每个进程创建的 inotify 文件描述符数量),可以通过以下几种方法实现:
方法一:使用 lsof
命令(简单直接)
lsof | grep inotify | awk '{print $2, $1}' | sort -n | uniq -c | sort -nr
输出示例:
3 12345 chrome2 67890 code1 23456 docker
解析:
- 每个
inotify
文件描述符对应一个 inotify instance。 - 统计结果中的数字表示该进程创建的 inotify instances 数量。
方法二:遍历 /proc
目录(更精确)
#!/bin/bashecho "INSTANCES PID COMMAND"
echo "--------- --- -------"for pid_dir in /proc/[0-9]*/; dopid=$(basename "$pid_dir")inotify_fd_count=$(ls -1 "$pid_dir/fd" 2>/dev/null | \xargs -I{} readlink -f "$pid_dir/fd/{}" 2>/dev/null | \grep -c 'anon_inode:inotify')if [ "$inotify_fd_count" -gt 0 ]; thencomm=$(cat "$pid_dir/comm" 2>/dev/null || echo "unknown")echo "$inotify_fd_count $pid $comm"fi
done | sort -rnk1
输出示例:
INSTANCES PID COMMAND
--------- --- -------3 12345 chrome2 67890 code1 23456 docker
方法三:Python 脚本(详细统计)
#!/usr/bin/env python3
import os
import re
from collections import defaultdictdef count_inotify_instances():instances = defaultdict(int)for pid in os.listdir('/proc'):if not pid.isdigit():continuetry:fd_dir = f'/proc/{pid}/fd'for fd in os.listdir(fd_dir):fd_path = os.readlink(f'{fd_dir}/{fd}')if 'anon_inode:inotify' in fd_path:instances[pid] += 1except (PermissionError, FileNotFoundError, OSError):continuereturn instancesdef get_process_name(pid):try:with open(f'/proc/{pid}/comm') as f:return f.read().strip()except (PermissionError, FileNotFoundError):return 'unknown'if __name__ == '__main__':instances = count_inotify_instances()print("PID\tINSTANCES\tPROCESS")for pid, count in sorted(instances.items(), key=lambda x: x[1], reverse=True):print(f"{pid}\t{count}\t\t{get_process_name(pid)}")
方法四:结合 sysdig
实时监控
sysdig -c spy_users inotify | grep 'inotify_init' | awk '{print $1, $2}' | sort | uniq -c
输出示例:
3 chrome2 code1 docker
高占用排查建议
- 识别异常进程:找出 instances 数量远高于其他进程的应用。
- 检查代码逻辑:对于开发中的应用,确保合理复用 inotify instances(而非频繁创建新实例)。
- 调整系统限制:如确实需要大量 instances,可增加
max_user_instances
:sysctl -w fs.inotify.max_user_instances=256 # 临时调整 echo "fs.inotify.max_user_instances=256" >> /etc/sysctl.conf # 永久调整
注意事项
- 权限问题:需要 root 权限才能查看所有进程的文件描述符。
- 容器环境:在容器内可能只能看到当前容器的 inotify 使用情况。
- 性能开销:遍历
/proc
目录会有一定性能开销,建议仅在必要时执行。
相关文章:
linux inotify 资源详解
Linux 的 inotify 是一个强大的文件系统监控机制,允许应用程序实时监听文件和目录的变化。这对于需要响应文件系统事件的应用(如配置热加载、备份工具、文件同步服务等)至关重要。以下是对 inotify 资源的深度解析: 一、核心概念…...
Java SE(8)——继承
1.继承的概念&作用 在Java中,继承是面向对象编程的三大基本特性之一(还有封装和多态),允许一个类(子类/继承类)继承另一个类(父类/基类)的属性和方法 继承的核心目的是…...
【论文笔记】SOTR: Segmenting Objects with Transformers
【题目】:SOTR: Segmenting Objects with Transformers 【引用格式】:Guo R, Niu D, Qu L, et al. Sotr: Segmenting objects with transformers[C]//Proceedings of the IEEE/CVF international conference on computer vision. 2021: 7157-7166. 【网…...
AIDC智算中心建设:资源池化核心技术解析
目录 一、池化技术架构 二、池化核心技术 三、展望 一、池化技术架构 智能算力池化指依托云计算技术,整合 GPU/AI 芯片等异构算力资源,构建集中管理的资源池,并按上层智算业务的需求,对池化的资源进行统一调度、分配ÿ…...
flink监控指标
文章目录 一、flink yaml配置二、配置指标项情况 提示:以下是基于开源flink on k8s环境下配置监控指标(部分已实验,粗略记录) 一、flink yaml配置 配置完成后就可以在页面查询(部分 需要验证)指标 二、配置指标项情况 参考下面网址: 阿里…...
签名去背景图像处理实例
一、前言 在生活中我们经常用到电子签名,但有时候我们所获取的图像的彩色图像,我们需要获取白底黑字的电子签名,我们可以通过下面程序对彩色图像进行处理达到我们的处理目的。 原始彩色图像如下: 二、原始代码 clear all;close a…...
[人机交互]理解与概念化交互
零.本章重点(理解和分析用户问题) – 解释“问题空间”的概念和含义 – 解释如何概念化交互 – 描述什么是概念模型 – 讨论将界面隐喻作为概念模型的利弊 – 讨论界面具体化和抽象化各自的优缺点 – 概述概念设计和实际设计的关系 一.理解问题空间 简单…...
C与指针——常见库函数
字符串 #include<stdlibs.h> int abs(int); long labs(long); int rand(void);//0-RAND_MAX //字符串转值 int atoi(const char*); long atol(const char*); float atof(const char*);数学\排序 #include<math.h> \\常见三角,sqrt(); exp(); double p…...
【C++指南】STL list容器完全解读(一):从入门到掌握基础操作
. 💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 文章目录 一、初识list容器1.1 什么是list?1.2 核心特性1.3 典型应用场景 二、核心成员函数…...
Auto.js 脚本:清理手机数据但保留账号
Auto.js 脚本:清理手机数据但保留账号 以下是一个使用 Auto.js 实现的脚本,它可以帮你清理手机数据(类似恢复出厂设置),同时尽可能保留已登录的账号状态。请注意,这个脚本不能完全等同于真正的恢复出厂设置…...
Web Workers 技术详解与最佳实践
Web Workers 是 HTML5 提供的一个强大的多线程解决方案,它允许在后台线程中运行 JavaScript 代码,从而避免阻塞主线程。本文将深入探讨 Web Workers 的技术实现和实际应用。 一、Web Workers 基础 1. 创建 Worker // 主线程代码 const worker new Wo…...
llama_factory0.9.3微调Qwen3
llama_factory微调QWen1.5-CSDN博客文章浏览阅读3.3k次,点赞36次,收藏10次。本文介绍了如何使用LLaMA-Factory微调Qwen1.5模型,包括1.8B和0.5B版本的训练细节。在数据、训练、LORA融合及...
Linux的时间同步服务器(附加详细实验案例)
一、计时方式的发展 1.古代计时方式 公元前约 2000 年:古埃及人利用光线留下的影子计时,他们修建高耸的大型方尖碑,通过追踪方尖碑影子的移动判断时间,这是早期利用自然现象计时的典型方式 。商朝时期:人们开发并…...
【全队项目】智能学术海报生成系统PosterGenius--前后端系统介绍
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀大模型实战训练营_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 一. 前…...
COlT_CMDB_linux_tomcat_20250505.sh
#!/bin/bash #IT_BEGIN #IT_TYPE3 #IT MIDWARE_TOMCAT_DISCOVERY|discovery.tomcat[disc] #原型指标 #IT_RULE MIDWARE_TOMCAT_IP|ip[{#CATALINA_BASE}] #IT_RULE MIDWARE_TOMCAT_Startpid|Start_pid[{#CATALINA_BASE}] #IT_RULE MIDWARE_TOMCAT_hostname|hostname[{#CATALINA_…...
【瞎折腾/mi50 32G/ubuntu】mi50显卡ubuntu运行大模型开坑(二)使用llama.cpp部署Qwen3系列
目录 说在前面准备工作编译llama.cpp运行Qwen3系列4B Q432B Q6温度 参考 说在前面 主板:未知x99cpu:E5 2666v3显卡:Mi 50 32G系统:ubuntu 22.04 准备工作 挂载磁盘(可选) 由于我的系统装在U盘上,访问文件系统会比较慢…...
《数据结构初阶》【顺序栈 + 链式队列 + 循环队列】
《数据结构初阶》【顺序栈 链式队列 循环队列】 前言:什么是栈?栈有哪些实现方式?我们要选择哪种实现方式?--------------------------------什么是队列?队列有哪些实现方式?我们要选择哪种实现方式&…...
TCP和UDP
一、基本概念 1. TCP(传输控制协议, Transmission Control Protocol) 面向连接(Connection-oriented):在传输数据前,要建立连接(三次握手)可靠:保证数据按顺…...
AI小智本地前后端部署
AI小智本地部署 1.安装phpstudy 1.1.安装该软件是为了获得web环境:MySQLApacherediophpmyadmin,介绍如下: ✅ 1. MySQL(数据库) 作用:关系型数据库管理系统,存储结构化数据,如用…...
springboot+mysql+element-plus+vue完整实现汽车租赁系统
目录 一、项目介绍 二、项目截图 1.项目结构图 三、系统详细介绍 管理后台 1.登陆页 2.管理后台主页 3.汽车地点管理 4.汽车类别 5.汽车品牌 6.汽车信息 7.用户管理 8.举报管理 9.订单管理 10.轮播图管理 11.交互界面 12.图表管理 汽车租赁商城 1.首页 2.汽…...
直方图比较
目录 1、直方图比较的概念 2、直方图比较的主要原因 3、典型应用场景 4、基础直方图比较 5、多通道直方图比较 6、实时直方图检测 1、直方图比较的概念 直方图比较是通过数学方法计算两个直方图之间的相似度或差异度的技术。在计算机视觉中,直方图是对图像特征…...
【计算机视觉】3d人体重建:PIFu/PIFuHD:高精度三维人体数字化技术指南
深度解析PIFu/PIFuHD:高精度三维人体数字化技术指南 一、项目概述与技术突破1.1 技术定位与核心价值1.2 性能指标对比1.3 技术演进路线 二、环境配置与模型部署2.1 硬件要求2.2 软件安装基础环境配置附加组件安装 2.3 模型下载 三、核心算法解析3.1 网络架构设计多层…...
HTML05:超链接标签及应用
链接标签 <a href"path" target"目标窗口位置">链接文本或图像</a>文本超链接图像超链接 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>链接标签学习</title&…...
JAVA设计模式——(十一)建造者模式(Builder Pattern)
JAVA设计模式——(十一)建造者模式(Builder Pattern) 介绍理解实现Phone类具体手机类建造者测试 应用 介绍 建造者模式用于将对象的创建和表示进行分离,即对象创建的过程单独提取出来,作为建造者的职能&am…...
JavaScript 笔记 --- part7 --- JS进阶 (part2)
JS进阶(part2) 内置构造函数 Object: 用于创建对象 String: 用于创建字符串 Number: 用于创建数字 Array: 用于创建数组 Boolean: 用于创建布尔值 Function: 用于创建函数 Date: 用于创建日期对象 RegExp: 用于创建正则表达式对象 Error: 用于创建错误对象 Map: 用于…...
JavaScript 笔记 --- part8 --- JS进阶 (part3)
JS 进阶(part3) 深浅拷贝 只针对引用类型 浅拷贝 浅拷贝只拷贝外面一层的属性, 如果对象里面还有对象, 那么这个对象的引用会被拷贝过去, 所以修改其中一个属性会影响到另一个对象 const obj {name: "zhangsan",age: 18,child: {name: "xiaoming",ag…...
LeetCode 热题 100 46. 全排列
LeetCode 热题 100 | 46. 全排列 大家好,今天我们来解决一道经典的算法题——全排列。这道题在 LeetCode 上被标记为中等难度,要求给定一个不含重复数字的数组 nums,返回其所有可能的全排列。全排列是排列组合中的经典问题,通常可…...
双目视觉的核心目标
通过计算左右图像中同一物体的像素点位置差(视差),进而还原出物体在三维空间中的真实位置。 双目视觉的核心流程: 1️⃣ 相机标定(calibration) 获取左右相机的内参、外参和畸变参数。 获取投影矩阵 Q&a…...
《类和对象(上)》
引言: 上次我们学习了C的一些入门基础,但其实还没有入门C,想要入门C,肯定是要把类和对象这部分学透彻,这次先来学习类和对象(上) 一:类的定义 1. 类定义格式: class为…...
强化学习ppo算法在大语言模型上跑通
最近在研究强化学习,目标是想在我的机械臂上跑出效果。ppo算法是强化学习领域的经典算法,在网上检索ppo算法,出现的大部分文章都是互相抄袭,上来都列公式,让人看得云里雾里。偶然间发现一个deepspeed使用的example(链接…...
告别散乱的 @ExceptionHandler:实现统一、可维护的 Spring Boot 错误处理
Spring Boot 的异常处理机制一直都烂得可以。即便到了 2025 年,有了这么多进步和新版本,开发者们发现自己还是在跟 ControllerAdvice、分散各处的 ExceptionHandler 方法以及五花八门的响应结构较劲。这真的是一团糟。 无论你是在构建 REST API、微服务…...
Ubuntu安装编译环境
1. 安装基础编译工具链(GCC, G, Make 等) sudo apt update # 只更新索引信息,不安装软件 sudo apt install build-essential这会安装以下核心组件: • gcc (GNU C 编译器) • g (GNU C 编译器) • make (构建工具) • libc-…...
Scrapy爬虫实战:如何用Rules实现高效数据采集
Scrapy是一个强大的Python爬虫框架,而其中的Rules类则为爬虫提供了更高级的控制方式。本文将详细介绍如何在Scrapy中使用Rules,以及各个参数的具体作用,并结合实际场景说明Rules的必要性。 为什么需要Rules? 在Web爬取过程中&…...
ERP系统源码,有演示,开发文档、数据库文档齐全,支持二次开发
一套开箱即用的云端ERP系统源代码,小型工厂ERP系统源码 SaaS ERP是一套开箱即用的云端ERP系统,有演示,开发文档,数据库文档齐全,自主版权落地实例,适合项目二开。 SaaS ERP具有高度的灵活性和可扩展性&am…...
如何将腾讯云的测试集成到自己的SpringBoot中
1.创建Util 我们将之前测试的test复制过来, 1.将方法里面的固定参数设置出来private 2.将方法里面的变化参数设置作为传入参数 3.返回String类型的URL地址 完整代码如下: package org.huangyingyuan.utils;import com.qcloud.cos.COSClient; import…...
Java后端开发day41--IO流(一)--FileOutputStreamFileInputStream
(以下内容全部来自上述课程) IO流:存储和读取数据的解决方案 I:input O:output 流:像水流一样传输数据 1. 流的分类 纯文本文件:Windows自带的记事本打开就能读懂 2. IO流的体系 3 字节流 3.1 FileOutputStream 操…...
Spring 框架中 @Configuration 注解详解
在 Spring 框架的开发过程中,Configuration注解是一个极为重要的存在,它让开发者能够以一种更加简洁、灵活的方式来管理应用程序的配置信息,极大地提升了开发效率和代码的可维护性。 本文将深入剖析Configuration注解的方方面面,…...
手机打电话时由对方DTMF响应切换多级IVR语音应答(一)
手机打电话时由对方DTMF响应切换多级IVR语音应答(一) --本地AI电话机器人 一、前言 经前面的系列篇章中,我们实现了拦截手机打电话的声音、根据通话对方声音提取DTMF字符。由此,我们通往AI电话机器人的道路就畅通无阻了。 如果…...
GM DC Monitor v2.0 - 平台自定义-使用说明
平台支持对LOGO、登录页背景图、平台名称、小标题名称、网址、告警中心、知识库名称进行自定义,自定义完以后,平台将更加适合您的工作场景! LOGO自定义建议使用100*80的png背景透明图片,大小不超过200k 登录背景建议使用1920*71…...
实验-数字电路设计2-复用器和七段数码管(数字逻辑)
目录 一、实验内容 二、实验步骤 2.1 复用器的设计 2.2 七段数码管的设计 三、调试过程 3.1 复用器调试过程 3.2 七段数码管的调试过程 四、实验使用环境 五、实验小结和思考 一、实验内容 a) 介绍 在这次实验中,你将熟悉 Logisim 的操作流程ÿ…...
HTTP/HTTPS协议(请求响应模型、状态码)
目录 HTTP/HTTPS协议简介 HTTP协议 HTTPS协议 请求 - 响应模型 HTTP请求 (二)HTTP响应 HTTPS协议与HTTP协议在请求 - 响应模型中的区别 HTTP/HTTPS协议简介 HTTP协议 定义 HTTP(HyperText Transfer Protocol)即超文本传输…...
详解RabbitMQ工作模式之路由模式
目录 路由模式 概念介绍 工作原理 特点 应用场景 实现步骤 代码案例 引入依赖 常量类 编写生产者代码 编写消费者1代码 编写消费者2代码 运行代码 路由模式 概念介绍 路由模式是发布订阅模式的变种, 在发布订阅基础上, 增加路由key。 发布订阅模式是⽆条件的将所有…...
青少年编程与数学 02-018 C++数据结构与算法 26课题、数据压缩算法
青少年编程与数学 02-018 C数据结构与算法 26课题、数据压缩算法 一、无损压缩算法1. Huffman编码2. Lempel-Ziv-Welch (LZW) 编码3. Run-Length Encoding (RLE) 二、有损压缩算法1. DEFLATE(ZIP压缩)2. Brotli3. LZMA4. Zstandard (Zstd) 总结 课题摘要…...
Sim Studio 是一个开源的代理工作流程构建器。Sim Studio 的界面是一种轻量级、直观的方式,可快速构建和部署LLMs与您最喜欢的工具连接
一、软件介绍 文末提供程序和源码下载 Sim Studio开源程序 是一个功能强大、用户友好的平台,用于构建、测试和优化代理工作流程,Sim Studio 是一个开源的代理工作流程构建器。Sim Studio 的界面是一种轻量级、直观的方式,可快速构建和部署…...
基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎
⭐️个人主页:小羊 ⭐️所属专栏:项目 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 项目背景技术栈和项目环境正排索引和倒排索引数据去标签与清洗下载数据源去标签 建立索引构建正排索引构建倒排索引 建立搜索引擎h…...
文本三剑客
目录 1.文本三剑客 2.awk 常见的内置变量 3.sed 选项: 脚本语法: 查找替换: 步进: 1.文本三剑客 awk;sed;grep 读取方式为:vim先将整个文件放入内存中进行编辑;awk是先将文…...
使用 Microsoft 365 Copilot 上传手机图片,实现更高效的信息提取
过去,如果你想从手机上的图片中提取信息或获取洞察,流程往往十分繁琐:需要先把图片发到邮箱,再下载到电脑,最后才能上传到 Copilot 聊天框中。 现在不必如此了!在你熟悉的 Microsoft 365 Windows 应用或网…...
simulink使能子系统的四种配置
目录 前言 一、模型 二、特性 组合1:使能模块为保持,输出为保持 组合2:使能模块为保持,输出为重置 组合3:使能模块为重置,输出为保持 组合4:使能模块为重置,输出为重置 仓库…...
一、Hadoop历史发展与优劣势
引言:大数据浪潮中的“大象”——Hadoop 的足迹与权衡 当数据以前所未有的速度和规模涌现,大数据时代悄然来临,传统的数据处理方式显得力不从心。在这样的背景下,Hadoop 应运而生,如同一头强健而可靠的大象࿰…...
conda配置好的pytorch在jupyter中如何配置
配置 其实不用再配置了 如下图(主要是激活pytorch环境,再jupyter notebook) jupyter运行快捷键shiftenter 新建文件夹folder,新建notebook 使用 帮助文档(两种方式) ctrl/ 注释...