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

Linux 内核遍历宏介绍

Linux内核中的遍历宏全面详解Linux内核中大量使用遍历宏Iteration Macros来简化数据结构的遍历操作。这些宏提供了类型安全、简洁且高效的遍历方式是内核编程的核心范式之一。一、遍历宏的分类1.1 按功能分类Linux内核遍历宏 ├── 链表遍历宏 │ ├── list_for_each_entry // 遍历标准链表 │ ├── hlist_for_each_entry // 遍历哈希链表 │ ├── list_for_each_entry_safe // 安全遍历可删除 │ └── list_for_each_entry_rcu // RCU保护遍历 │ ├── CPU遍历宏 │ ├── for_each_possible_cpu // 所有可能的CPU │ ├── for_each_online_cpu // 在线CPU │ ├── for_each_present_cpu // 存在的CPU │ └── for_each_cpu_and // CPU掩码交集 │ ├── 进程遍历宏 │ ├── for_each_process // 遍历所有进程 │ ├── for_each_thread // 遍历进程的线程 │ └── for_each_task_pid // 遍历特定PID的进程 │ ├── 内存遍历宏 │ ├── for_each_sg // 遍历scatter-gather列表 │ ├── for_each_vma // 遍历虚拟内存区域 │ └── for_each_zone // 遍历内存区域 │ ├── 文件系统遍历宏 │ ├── for_each_mount_point // 遍历挂载点 │ ├── for_each_dentry // 遍历目录项 │ └── for_each_inode // 遍历inode │ ├── 设备遍历宏 │ ├── for_each_netdev // 遍历网络设备 │ ├── for_each_pci_dev // 遍历PCI设备 │ └── for_each_irq // 遍历中断 │ └── 定时器遍历宏 ├── for_each_timer // 遍历定时器 └── for_each_hrtimer // 遍历高精度定时器二、链表遍历宏最常用2.1 标准链表遍历#includelinux/list.hstructmy_struct{intdata;structlist_headlist;// 链表节点};structlist_headhead;INIT_LIST_HEAD(head);// 1. 基本遍历不可删除节点structmy_struct*entry;list_for_each_entry(entry,head,list){printk(data: %d\n,entry-data);}// 2. 安全遍历可删除当前节点structmy_struct*entry,*tmp;list_for_each_entry_safe(entry,tmp,head,list){if(entry-data0){list_del(entry-list);kfree(entry);}}// 3. 反向遍历list_for_each_entry_reverse(entry,head,list){printk(data: %d\n,entry-data);}// 4. 从指定位置开始遍历structmy_struct*entry;list_for_each_entry_from(entry,head,list){// 从entry开始继续遍历}// 5. 带锁的安全遍历spin_lock(lock);list_for_each_entry(entry,head,list){// 在锁保护下遍历}spin_unlock(lock);2.2 RCU保护的链表遍历#includelinux/rculist.hstructmy_struct{intdata;structlist_headlist;structrcu_headrcu;};structlist_headhead;// RCU读锁保护rcu_read_lock();structmy_struct*entry;list_for_each_entry_rcu(entry,head,list){printk(data: %d\n,entry-data);}rcu_read_unlock();// RCU安全删除list_del_rcu(entry-list);call_rcu(entry-rcu,my_struct_free);2.3 哈希链表遍历#includelinux/list.h#defineHASH_SIZE256structhlist_headhash_table[HASH_SIZE];structmy_struct{intkey;structhlist_nodenode;// 哈希链表节点};// 遍历单个哈希桶structmy_struct*entry;structhlist_head*headhash_table[hash_index];hlist_for_each_entry(entry,head,node){if(entry-keytarget_key){// 找到目标break;}}// 安全遍历可删除structmy_struct*entry,*tmp;hlist_for_each_entry_safe(entry,tmp,head,node){if(entry-keytarget_key){hlist_del(entry-node);kfree(entry);}}// RCU保护的哈希链表遍历rcu_read_lock();hlist_for_each_entry_rcu(entry,head,node){printk(key: %d\n,entry-key);}rcu_read_unlock();2.4 链表遍历宏详解宏名称用途是否可删除节点线程安全list_for_each_entry标准正向遍历否需外部锁list_for_each_entry_safe安全遍历支持删除是需外部锁list_for_each_entry_reverse反向遍历否需外部锁list_for_each_entry_rcuRCU保护遍历否RCU保护list_for_each_entry_safe_rcuRCU安全遍历是RCU保护hlist_for_each_entry哈希链表遍历否需外部锁hlist_for_each_entry_safe哈希链表安全遍历是需外部锁三、CPU遍历宏3.1 基本CPU遍历#includelinux/cpumask.h// 1. 遍历所有可能的CPUintcpu;for_each_possible_cpu(cpu){structper_cpu_data*dataper_cpu_ptr(my_data,cpu);init_percpu_data(data);}// 2. 遍历在线CPUfor_each_online_cpu(cpu){smp_call_function_single(cpu,work_func,NULL,1);}// 3. 遍历存在的CPUfor_each_present_cpu(cpu){init_cpu_hardware(cpu);}// 4. 遍历活跃CPU用于调度for_each_active_cpu(cpu){assign_task_to_cpu(cpu);}// 5. 遍历CPU掩码的交集for_each_cpu_and(cpu,cpu_online_mask,cpu_active_mask){// 处理既在线又活跃的CPU}3.2 CPU遍历宏详解// 实现原理#definefor_each_possible_cpu(cpu)\for_each_cpu((cpu),cpu_possible_mask)#definefor_each_cpu(cpu,mask)\for((cpu)-1;\(cpu)cpumask_next((cpu),(mask)),\(cpu)nr_cpu_ids;)// 实际使用示例voidshow_cpu_status(void){intcpu;charbuf[128];// 打印在线CPU列表cpumap_print_to_pagebuf(true,buf,cpu_online_mask);pr_info(Online CPUs: %s\n,buf);// 为每个在线CPU执行操作for_each_online_cpu(cpu){pr_info(CPU%d: status%s\n,cpu,cpu_online(cpu)?online:offline);}}四、进程遍历宏4.1 进程遍历#includelinux/sched.h// 1. 遍历所有进程structtask_struct*p;for_each_process(p){printk(Process: %s (PID: %d)\n,p-comm,p-pid);}// 2. 遍历进程的所有线程structtask_struct*thread;for_each_thread(p,thread){printk(Thread: %s (TID: %d)\n,thread-comm,thread-pid);}// 3. 遍历特定PID命名空间的进程structpid_namespace*pid_nstask_active_pid_ns(current);structtask_struct*p;for_each_process_in_pid_ns(pid_ns,p){// 处理该命名空间的进程}// 4. 安全遍历防止进程退出structtask_struct*p,*tmp;read_lock(tasklist_lock);for_each_process_safe(p,tmp){// 在锁保护下遍历可以安全地处理get_task_struct(p);// 增加引用计数// ... 处理进程 ...put_task_struct(p);}read_unlock(tasklist_lock);4.2 进程遍历注意事项// 错误遍历时可能导致进程退出for_each_process(p){// 进程p可能在这之后退出printk(%s\n,p-comm);// 危险}// 正确使用RCU保护rcu_read_lock();for_each_process(p){// RCU保护下进程不会退出printk(%s\n,p-comm);}rcu_read_unlock();// 正确使用引用计数structtask_struct*p;for_each_process(p){get_task_struct(p);// 防止进程退出// 安全使用pput_task_struct(p);}五、内存区域遍历宏5.1 内存区域遍历#includelinux/mm.h// 遍历进程的虚拟内存区域structmm_struct*mmcurrent-mm;structvm_area_struct*vma;down_read(mm-mmap_lock);for_each_vma(vma,mm){printk(VMA: 0x%lx-0x%lx flags0x%lx\n,vma-vm_start,vma-vm_end,vma-vm_flags);}up_read(mm-mmap_lock);// 遍历内存节点intnid;for_each_node(nid){structpglist_data*pgdatNODE_DATA(nid);printk(Node %d: start_pfn0x%lx\n,nid,pgdat-node_start_pfn);}// 遍历内存区域structzone*zone;for_each_zone(zone){printk(Zone: %s, pages%lu\n,zone-name,zone-managed_pages);}六、设备遍历宏6.1 网络设备遍历#includelinux/netdevice.h// 遍历所有网络设备structnet_device*dev;for_each_netdev(init_net,dev){printk(Device: %s, state%d\n,dev-name,dev-state);}// 安全遍历可删除设备structnet_device*dev,*tmp;for_each_netdev_safe(init_net,dev,tmp){if(should_remove(dev)){unregister_netdev(dev);}}// 遍历特定命名空间的网络设备structnet*netcurrent-nsproxy-net_ns;for_each_netdev(net,dev){// 处理该命名空间的设备}6.2 PCI设备遍历#includelinux/pci.h// 遍历所有PCI设备structpci_dev*pdev;for_each_pci_dev(pdev){printk(PCI: %04x:%04x\n,pdev-vendor,pdev-device);}// 遍历特定总线的设备structpci_bus*bus;for_each_pci_bus(bus){printk(PCI Bus: %02x\n,bus-number);}七、文件系统遍历宏7.1 挂载点遍历#includelinux/mount.h// 遍历所有挂载点structmount*mnt;for_each_mount(mnt){printk(Mount: %s on %s\n,mnt-mnt_devname,mnt-mnt.mnt_root-d_name.name);}7.2 目录项遍历#includelinux/dcache.h// 遍历目录下的所有目录项structdentry*parentdir-dentry;structdentry*dentry;spin_lock(parent-d_lock);list_for_each_entry(dentry,parent-d_subdirs,d_child){printk(Dentry: %s\n,dentry-d_name.name);}spin_unlock(parent-d_lock);八、定时器遍历宏8.1 定时器遍历#includelinux/timer.h// 遍历定时器调试用structtimer_list*timer;structtimer_base*basethis_cpu_ptr(timer_bases[BASE_STD]);spin_lock(base-lock);for_each_timer(timer,base){printk(Timer: expires%lu, function%pS\n,timer-expires,timer-function);}spin_unlock(base-lock);九、自定义遍历宏9.1 创建自定义遍历宏// 1. 定义数据结构structmy_array{int*items;intsize;};// 2. 创建遍历宏#definefor_each_my_array(item,array)\for(int__i0;\(__i(array)-size)((item)(array)-items[__i],1);\__i)// 3. 使用structmy_arrayarr;int*item;for_each_my_array(item,arr){printk(Item: %d\n,*item);}// 4. 带索引的遍历宏#definefor_each_my_array_idx(item,idx,array)\for((idx)0;\((idx)(array)-size)((item)(array)-items[idx],1);\(idx))// 使用intidx;for_each_my_array_idx(item,idx,arr){printk(arr[%d] %d\n,idx,*item);}9.2 复杂数据结构的遍历宏// 树形结构遍历宏structtree_node{structtree_node*parent;structlist_headchildren;intdata;};#definefor_each_tree_child(child,parent)\list_for_each_entry(child,(parent)-children,node)#definefor_each_tree_descendant(node,root)\for((node)(root);(node);(node)next_tree_node(node))// 使用structtree_node*root;structtree_node*child;structtree_node*desc;for_each_tree_child(child,root){printk(Child: %d\n,child-data);}for_each_tree_descendant(desc,root){printk(Descendant: %d\n,desc-data);}十、遍历宏的性能优化10.1 预取优化// 使用prefetch预取下一个元素structmy_struct*entry;list_for_each_entry(entry,head,list){prefetch(entry-list.next);// 预取下一个节点process_entry(entry);}10.2 缓存友好遍历// 不好的遍历跳跃访问for_each_possible_cpu(cpu){structdata*dper_cpu_ptr(my_data,cpu);d-counter;// 可能跨CPU缓存行}// 好的遍历本地访问intcpuget_cpu();structdata*dthis_cpu_ptr(my_data);d-counter;put_cpu();十一、常见错误与调试11.1 遍历时删除节点的错误// 错误遍历时删除导致崩溃structmy_struct*entry;list_for_each_entry(entry,head,list){if(entry-data0){list_del(entry-list);// 错误破坏了遍历kfree(entry);}}// 正确使用_safe版本structmy_struct*entry,*tmp;list_for_each_entry_safe(entry,tmp,head,list){if(entry-data0){list_del(entry-list);kfree(entry);}}11.2 遍历时缺少锁保护// 错误无锁遍历并发修改的链表list_for_each_entry(entry,head,list){// 其他CPU可能正在修改链表process_entry(entry);}// 正确使用锁保护spin_lock(list_lock);list_for_each_entry(entry,head,list){process_entry(entry);}spin_unlock(list_lock);11.3 调试技巧// 打印链表信息voiddump_list(structlist_head*head){structmy_struct*entry;intcount0;pr_info(List dump:\n);list_for_each_entry(entry,head,list){pr_info( [%d] data%d, next%p, prev%p\n,count,entry-data,entry-list.next,entry-list.prev);}pr_info(Total: %d entries\n,count);}// 使用lockdep检查锁lockdep_assert_held(list_lock);list_for_each_entry(entry,head,list){// 确保锁已持有}十二、总结12.1 遍历宏的核心特点类型安全通过宏参数传递类型避免强制转换简洁高效减少重复代码编译器优化好模式统一所有遍历宏遵循相似的使用模式上下文感知有些宏需要特定的锁或RCU保护12.2 选择指南场景推荐遍历宏原因标准链表操作list_for_each_entry最常用性能好需要删除节点list_for_each_entry_safe保存了next指针RCU保护读取list_for_each_entry_rcuRCU语义正确哈希表遍历hlist_for_each_entry适合哈希桶CPU相关操作for_each_online_cpu只处理在线CPU进程遍历RCU保护的遍历进程可能退出网络设备for_each_netdev网络子系统标准内存区域RCU或锁保护VMA可能改变12.3 最佳实践总是使用正确的遍历宏普通/安全/RCU在需要时使用适当的锁保护避免在遍历中长时间阻塞使用prefetch优化长链表遍历注意遍历方向对缓存的影响自定义遍历宏时保持内核风格遍历宏是Linux内核代码中最常见的模式之一理解并正确使用它们对于编写高效、安全的内核代码至关重要。

相关文章:

Linux 内核遍历宏介绍

Linux内核中的遍历宏全面详解 Linux内核中大量使用遍历宏(Iteration Macros)来简化数据结构的遍历操作。这些宏提供了类型安全、简洁且高效的遍历方式,是内核编程的核心范式之一。一、遍历宏的分类 1.1 按功能分类 Linux内核遍历宏 ├── 链…...

Pixel Script Temple 数学建模辅助:将MATLAB算法思路转换为Python代码

Pixel Script Temple 数学建模辅助:将MATLAB算法思路转换为Python代码 1. 为什么需要MATLAB到Python的代码转换 在科研和工程领域,MATLAB长期以来一直是数学建模和科学计算的首选工具。但随着Python生态系统的成熟,越来越多的团队开始转向使…...

Phi-3-mini-4k-instruct-gguf效果实测:128ms首token延迟+98%中文基础任务通过率

Phi-3-mini-4k-instruct-gguf效果实测:128ms首token延迟98%中文基础任务通过率 1. 开篇:轻量级文本生成新选择 最近测试了微软Phi-3系列中的轻量级选手——Phi-3-mini-4k-instruct-gguf模型,结果让人惊喜。这个专门优化过的GGUF版本&#x…...

HumanoidVerse深度解析:如何通过多模拟器框架实现人形机器人sim2real高效训练

1. HumanoidVerse框架概览:多模拟器支持与模块化设计 HumanoidVerse是卡耐基梅隆大学(CMU)推出的开源框架,专门针对人形机器人的sim2real训练需求。这个框架最大的特点在于其多模拟器支持架构,能够无缝对接IsaacGym、IsaacSim和Genesis三种主…...

别再死记硬背了!用DCM模式反激电路,手把手教你搞定宽电压输入的隔离电源

从零构建宽电压隔离电源:DCM反激电路实战指南 当你在深夜调试电路时突然闻到焦糊味,或是面对一堆烧毁的MOS管束手无策,是否想过——电源设计本可以更简单?本文将带你用工程师的思维重新理解反激变换器,避开教科书式的理…...

像素皇城灵蛇贺岁:5分钟部署你的赛博春联生成器(保姆级教程)

像素皇城灵蛇贺岁:5分钟部署你的赛博春联生成器(保姆级教程) 1. 前言:当传统春节遇上赛博美学 春节贴春联是延续千年的传统习俗,但你是否想过用AI技术为这个传统注入新的活力?今天我们要介绍的"像素…...

Python打包神器大PK:Nuitka vs PyInstaller,谁才是你的菜?(附实测数据)

Python打包工具深度评测:Nuitka与PyInstaller的终极对决 当开发者需要将Python项目分发给没有Python环境的用户时,打包工具的选择往往成为关键决策。本文将深入分析两大主流工具Nuitka和PyInstaller在多个维度的表现,帮助开发者根据项目需求做…...

Qwen3.5-2B效果展示:儿童绘本图→识别角色/场景/情绪→生成故事续写+朗读脚本

Qwen3.5-2B效果展示:儿童绘本图→识别角色/场景/情绪→生成故事续写朗读脚本 1. 模型介绍 Qwen3.5-2B是通义千问团队推出的轻量化多模态基础模型,属于Qwen3.5系列的小参数版本(20亿参数)。这个模型特别适合在资源有限的设备上部…...

长上下文与RAG

读到一篇探讨RAG技术的文章,很受用,遂记录一下。核心结论:RAG不会被无限上下文取代。 原文地址:LLM无限上下文了,RAG(Retrieval Augmented Generation)还有意义吗? - 今日头条 以下…...

Python 3.14 JIT架构深度拆解(含官方未发布IR层流程图+Hot Code Path决策树)

第一章:Python 3.14 JIT编译器演进背景与设计哲学Python 长期以来以解释执行和动态灵活性著称,但性能瓶颈在数值计算、实时服务与高吞吐系统中日益凸显。CPython 解释器的字节码执行模型虽稳定可靠,却难以突破单线程 GIL 与逐指令解释带来的固…...

MAI-UI-8B入门:Node.js环境配置与自动化测试

MAI-UI-8B入门:Node.js环境配置与自动化测试 1. 开篇:为什么选择MAI-UI-8B进行自动化测试 如果你正在寻找一个能够真正理解图形界面、像真人一样操作应用的自动化测试方案,MAI-UI-8B绝对值得关注。这个由阿里通义实验室开源的GUI智能体模型…...

OpenClaw创始人加入OpenAI:这不是跳槽新闻,是整个AI行业换挡的信号

OpenClaw创始人加入OpenAI:这不是跳槽新闻,是整个AI行业换挡的信号摘要OpenClaw创始人Peter Steinberger正式加入OpenAI,项目移交开源基金会。Sam Altman亲自官宣,称他是"天才"。这件事的真正意义不在人事变动&#xff…...

PasteMD体验报告:极简界面+强大功能,这才是生产力工具该有的样子

PasteMD体验报告:极简界面强大功能,这才是生产力工具该有的样子 1. 重新定义"文本整理":当AI成为你的第二大脑 每天,我们都在与各种杂乱文本搏斗:会议速记、技术日志、网页摘录、临时灵感...这些内容往往以…...

intv_ai_mk11开源模型教程:7B Llama架构对话机器人在GPU云上的安全沙箱实践

intv_ai_mk11开源模型教程:7B Llama架构对话机器人在GPU云上的安全沙箱实践 1. 什么是intv_ai_mk11对话机器人 intv_ai_mk11是一个基于7B参数Llama架构的AI对话助手,专门设计运行在GPU云服务器环境中。这个模型经过优化,能够在保持较高响应…...

MusePublic圣光艺苑惊艳效果:大气照明+表达性纹理细节放大展示

MusePublic圣光艺苑惊艳效果:大气照明表达性纹理细节放大展示 1. 引言:当古典艺术遇见AI算力 想象一下,你走进一间19世纪的画室。空气中弥漫着亚麻籽油和矿物颜料的味道,阳光透过高窗洒在亚麻画布上,墙上挂着鎏金画框…...

南京大学发布“视频侦探“系统:让AI像侦探一样从长视频中找线索

这项由南京大学与中科院自动化所联合进行的研究发表于2026年的计算机视觉与模式识别(CVPR)会议,论文编号为arXiv:2603.22285。有兴趣深入了解的读者可以通过该编号查询完整论文内容。当我们观看一部两小时的电影时,想要回答"主角在什么时候第一次露…...

JIT热路径识别失效?手撕Python 3.14 _pyjitsymbol.c源码,定位3个未文档化的profile阈值陷阱(内附补丁POC)

第一章:JIT热路径识别失效?手撕Python 3.14 _pyjitsymbol.c源码,定位3个未文档化的profile阈值陷阱(内附补丁POC)Python 3.14 引入的 _pyjitsymbol JIT 框架在实际压测中频繁出现热路径“失焦”现象:高频率…...

8种Prompt优化技巧:解决大模型输出不稳定痛点

8种Prompt优化技巧:解决大模型输出不稳定痛点 在大模型应用落地过程中,开发者常遇到输出结果不可控的问题:同样的需求多次调用返回内容差异巨大、回答偏离核心要求、格式混乱无法直接解析,这些问题严重影响业务流程的稳定性和用户…...

多模态Agent架构实战落地:从需求分析到生产部署

多模态Agent架构实战落地:从需求分析到生产部署 随着大语言模型技术的普及,单一文本交互的智能系统已无法满足复杂业务场景需求——电商平台需要同时理解用户的商品描述文本、实拍图片和售后语音诉求,教育场景需要处理手写作业、视频讲解和文…...

Win11Debloat:让你的Windows系统重获新生的终极优化指南

Win11Debloat:让你的Windows系统重获新生的终极优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …...

fre:ac开源音频转换工具:让无损音乐在全设备自由流动的专业级解决方案

fre:ac开源音频转换工具:让无损音乐在全设备自由流动的专业级解决方案 【免费下载链接】freac The fre:ac audio converter project 项目地址: https://gitcode.com/gh_mirrors/fr/freac 你是否遇到过这些音乐管理难题:珍藏多年的CD专辑不知如何数…...

VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍

VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍 【免费下载链接】VRCT VRCT(VRChat Chatbox Translator & Transcription) 项目地址: https://gitcode.com/gh_mirrors/vr/VRCT 您是否曾在VRChat的国际房间中,面对来自…...

服务器很卡,是CC攻击造成的吗

之前有客户反馈,服务器有一段时间使用总是会遇到卡的情况,查看并无流量攻击的情况,程序也未进行过什么修改,用户人数也没有什么变化。来咨询是什么原因导致的。导致机器卡的情况,一般有带宽不够,硬件性能不…...

别再死记硬背了!用eNSP模拟一个500人公司的真实网络(含VLAN、MSTP、VRRP完整配置)

从零构建500人企业网络:eNSP实战中的VLAN、MSTP与VRRP深度解析 当你第一次面对企业级网络规划时,是否曾被各种协议和配置弄得晕头转向?本文将以一个真实的500人企业网络为蓝本,带你用华为eNSP模拟器完成从需求分析到最终实现的完整…...

Qwen3.5-9B-AWQ-4bitWeb界面使用教程:上传/提问/防重复提交/结果解析全流程

Qwen3.5-9B-AWQ-4bit Web界面使用教程:上传/提问/防重复提交/结果解析全流程 1. 认识Qwen3.5-9B-AWQ-4bit模型 Qwen3.5-9B-AWQ-4bit是一个强大的多模态AI模型,它能够同时理解图片和文字。想象一下,你有一个既会看图片又会回答问题的智能助手…...

Ubuntu安装中文输入法后无法输入中文----问题分析及解决方法

问题:之前在Ubuntu系统上安装过搜狗输入法,且能正常输入中文。但重启之后无法调出,Shift切换也不管用,依旧是英文原因分析:后台进程(Fcitx)卡死或崩溃了解决方法:重启Fcitx输入法框架…...

从‘硬’开关到‘软’启动:拆解一个经典PMOS缓启动电路,聊聊D4、D6这些二极管到底在忙啥?

从‘硬’开关到‘软’启动:拆解一个经典PMOS缓启动电路,聊聊D4、D6这些二极管到底在忙啥? 在硬件设计中,电源管理电路如同交响乐团的指挥,协调着各个器件的动作节奏。而缓启动电路,则是这位指挥手中那根至关…...

3步搭建PP-DocLayoutV3服务:快速体验文档版面分析的强大能力

3步搭建PP-DocLayoutV3服务:快速体验文档版面分析的强大能力 1. 引言:文档版面分析的价值 在日常工作中,我们经常需要处理各种文档——合同、论文、报告、书籍等。传统OCR技术虽然能识别文字,但往往无法理解文档的结构&#xff…...

别再只改默认密码了!Nacos 1.x/2.x 生产环境安全加固保姆级清单(附漏洞自查脚本)

Nacos生产环境安全加固全指南:从基础配置到漏洞防御 在微服务架构盛行的今天,Nacos作为服务发现和配置管理的核心组件,其安全性直接影响整个系统的稳定性。许多团队在部署Nacos时往往只满足于修改默认密码,却忽视了完整的安全防护…...

C语言调用Omni-Vision Sanctuary轻量级推理接口(C API)教程

C语言调用Omni-Vision Sanctuary轻量级推理接口(C API)教程 1. 引言:为什么选择C API? 在嵌入式设备和资源受限的环境中,Python运行时往往显得过于臃肿。Omni-Vision Sanctuary提供的C语言接口(C API&…...