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

Linux CFS 的 switched_from/switched_to:调度类切换的处理

一、简介在Linux内核的调度子系统中任务在不同调度类之间切换是一个复杂且关键的操作。当应用程序调用sched_setscheduler()将任务从普通调度策略SCHED_NORMAL切换为实时策略SCHED_FIFO/SCHED_RR或者从实时策略降级为普通策略时内核必须完成一系列精细的状态迁移操作。CFSCompletely Fair Scheduler作为Linux默认的普通任务调度器通过switched_from_fair()和switched_to_fair()这两个回调函数来处理任务进出CFS调度类的状态转换。这两个函数定义在fair_sched_class调度类中是struct sched_class接口的重要组成部分。掌握这一机制对于以下场景至关重要实时系统调优理解任务在RT与CFS之间切换时的延迟开销容器资源管控分析CFS Bandwidth Control在调度类切换时的节流行为性能问题定位排查因调度类切换导致的vruntime异常或负载不均衡问题内核开发编写自定义调度类或修改现有调度逻辑时的参考实现二、核心概念2.1 调度类sched_class架构Linux内核采用模块化调度类设计每个调度类通过struct sched_class结构体注册一组回调函数。CFS调度类的定义位于kernel/sched/fair.c其核心回调包括const struct sched_class fair_sched_class { .enqueue_task enqueue_task_fair, .dequeue_task dequeue_task_fair, .pick_next_task pick_next_task_fair, .task_tick task_tick_fair, .switched_from switched_from_fair, // 离开CFS时调用 .switched_to switched_to_fair, // 进入CFS时调用 .prio_changed prio_changed_fair, // ... 其他回调 };2.2 调度实体sched_entity与CFS运行队列cfs_rq每个任务在CFS中通过sched_entity结构体表示该实体维护着关键的调度状态vruntime虚拟运行时间决定任务在红黑树中的位置load.weight权重值反映任务的优先级on_rq标记任务是否已在运行队列中cfs_rq指向任务所属CFS运行队列的指针当任务在不同CPU或不同cgroup之间迁移时必须正确处理这些状态字段以保证调度公平性。2.3 调度类切换的触发点调度类切换通常发生在以下场景显式策略变更用户调用sched_setscheduler()修改任务调度策略优先级继承PIRT互斥锁导致的优先级提升/恢复cgroup迁移任务在不同CPU cgroup之间移动时可能涉及调度类变更核心切换逻辑位于check_class_changed()函数void check_class_changed(struct rq *rq, struct task_struct *p, const struct sched_class *prev_class, int oldprio) { if (prev_class ! p-sched_class) { if (prev_class-switched_from) prev_class-switched_from(rq, p); // 旧类清理 p-sched_class-switched_to(rq, p); // 新类初始化 } else if (oldprio ! p-prio) { p-sched_class-prio_changed(rq, p, oldprio); } }三、环境准备3.1 硬件与软件要求组件最低要求推荐配置CPU架构x86_64/arm64x86_64多核内存4GB8GB操作系统Linux 5.4Linux 6.6 LTS内核源码完整源码树带debuginfo的源码编译工具gcc 9gcc 12调试工具perf, ftracebpftrace, kernelshark3.2 内核编译与配置# 1. 获取内核源码 git clone https://github.com/torvalds/linux.git cd linux git checkout v6.6 # 2. 配置内核选项关键调度相关配置 make menuconfig # 必须启用的选项 # CONFIG_SCHED_DEBUGy # 调度器调试 # CONFIG_CGROUP_SCHEDy # cgroup调度支持 # CONFIG_FAIR_GROUP_SCHEDy # CFS组调度 # CONFIG_CFS_BANDWIDTHy # CFS带宽控制 # CONFIG_SCHEDSTATSy # 调度统计信息 # 3. 编译并安装 make -j$(nproc) sudo make modules_install sudo make install3.3 调试环境搭建# 安装调试工具 sudo apt-get install -y \ linux-headers-$(uname -r) \ bpftrace \ trace-cmd \ kernelshark \ sysstat # 挂载debugfs以访问调度器调试信息 sudo mount -t debugfs none /sys/kernel/debug # 启用调度器事件跟踪 echo 1 /sys/kernel/debug/tracing/events/sched/sched_switch/enable echo 1 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable四、应用场景在工业自动化控制系统中典型的应用场景是PLC可编程逻辑控制器软实时任务与后台数据分析任务的混合部署。假设某产线监控系统需要数据采集任务以SCHED_FIFO策略运行优先级50周期1ms采集传感器数据日志处理任务以SCHED_NORMAL策略运行批量处理历史数据动态降级机制当系统负载过高时将非关键RT任务降级为CFS任务在这种场景下当运维人员通过sched_setscheduler()将日志处理任务从SCHED_NORMAL切换为SCHED_BATCH以优化吞吐量时内核会触发switched_from_fair()完成CFS状态的清理反之当系统负载降低需要将某个CFS任务提升为RT任务时switched_to_fair()的逆过程会被执行。理解这两个函数的底层实现有助于预测调度延迟、分析上下文切换开销并设计合理的任务迁移策略。五、实际案例与步骤5.1 案例一从CFS切换到RT类switched_from_fair分析当任务从CFS切换到RT调度类时switched_from_fair()负责清理任务在CFS中的状态。// 位于 kernel/sched/fair.c static void switched_from_fair(struct rq *rq, struct task_struct *p) { // 1. 将任务从其所属的cfs_rq中分离 detach_task_cfs_rq(p); // 2. 如果启用了CFS带宽控制取消任务的节流状态 if (cfs_bandwidth_used()) task_throttle_cancel(p); }detach_task_cfs_rq()的核心逻辑static void detach_task_cfs_rq(struct task_struct *p) { struct sched_entity *se p-se; struct cfs_rq *cfs_rq cfs_rq_of(se); // 如果任务当前在运行队列上先出队 if (task_on_rq_queued(p)) { dequeue_entity(cfs_rq, se, DEQUEUE_SAVE | DEQUEUE_MOVE); } // 分离任务组关联如果启用了组调度 #ifdef CONFIG_FAIR_GROUP_SCHED if (se-cfs_rq) { // 更新cfs_rq的负载统计 update_cfs_rq_load_avg(cfs_rq); // 从父调度实体链中分离 for_each_sched_entity(se) { struct cfs_rq *qcfs_rq cfs_rq_of(se); if (qcfs_rq-tg) set_task_rq(p, task_cpu(p)); } } #endif // 清除任务在CFS中的运行时统计关联 se-cfs_rq NULL; }操作步骤与验证# 步骤1创建测试任务并监控其调度状态 cat /tmp/test_task.c EOF #include stdio.h #include stdlib.h #include sched.h #include unistd.h #include sys/syscall.h int main() { pid_t pid getpid(); struct sched_param param; printf(Task %d started with policy %d\n, pid, sched_getscheduler(0)); // 模拟工作负载 for (int i 0; i 5; i) { sleep(1); // 切换到SCHED_FIFO param.sched_priority 50; if (sched_setscheduler(0, SCHED_FIFO, param) -1) { perror(sched_setscheduler); exit(1); } printf(Switched to SCHED_FIFO, priority %d\n, param.sched_priority); sleep(1); // 切换回SCHED_NORMAL param.sched_priority 0; if (sched_setscheduler(0, SCHED_NORMAL, param) -1) { perror(sched_setscheduler); exit(1); } printf(Switched back to SCHED_NORMAL\n); } return 0; } EOF gcc -o /tmp/test_task /tmp/test_task.c # 步骤2使用ftrace跟踪调度类切换 sudo trace-cmd start -e sched_switch -e sched_wakeup -e sched_setscheduler /tmp/test_task sudo trace-cmd stop sudo trace-cmd report /tmp/sched_trace.txt # 步骤3分析trace结果观察switched_from/switched_to调用路径 grep -A 5 -B 5 sched_setscheduler\|switched_from\|switched_to /tmp/sched_trace.txt5.2 案例二从RT类切换到CFSswitched_to_fair分析当任务从RT类降级到CFS时switched_to_fair()负责初始化任务在CFS中的状态static void switched_to_fair(struct rq *rq, struct task_struct *p) { // 1. 将任务附加到目标cfs_rq attach_task_cfs_rq(p); // 2. 如果启用了带宽控制且任务需要节流设置节流状态 if (cfs_bandwidth_used() task_needs_throttling(p)) task_throttle_setup(p); // 3. 设置任务的最大允许容量与CPU容量管理相关 set_task_max_allowed_capacity(p); // 4. 如果任务在运行队列上检查是否需要抢占当前任务 if (task_on_rq_queued(p)) { /* * 任务很可能从sched_rt切换而来如果当前正在运行则触发调度 * 否则检查是否还能抢占当前任务 */ if (rq-curr p) resched_curr(rq); // 触发重新调度 else check_preempt_curr(rq, p, 0); // 检查抢占条件 } }attach_task_cfs_rq()的核心逻辑static void attach_task_cfs_rq(struct task_struct *p) { struct sched_entity *se p-se; struct cfs_rq *cfs_rq cfs_rq_of(se); // 设置任务所属的cfs_rq se-cfs_rq cfs_rq; // 初始化或同步vruntime if (!se-avg.last_update_time) { // 新加入CFS的任务需要合理设置初始vruntime place_entity(cfs_rq, se, 0); } else { // 从其他CPU迁移或从RT降级同步min_vruntime基准 se-vruntime cfs_rq-min_vruntime; } // 如果任务在运行队列上执行入队操作 if (task_on_rq_queued(p)) { enqueue_entity(cfs_rq, se, ENQUEUE_WAKEUP); update_load_avg(cfs_rq, se, 0); } #ifdef CONFIG_FAIR_GROUP_SCHED // 更新任务组层级结构 if (se-cfs_rq-tg) { update_cfs_rq_load_avg(cfs_rq); propagate_entity_cfs_rq(se); } #endif }vruntime同步的关键性当任务从RT切换到CFS时必须正确处理vruntime否则会导致严重的公平性问题// vruntime同步示例代码概念性展示 static inline void sync_vruntime(struct sched_entity *se, struct cfs_rq *cfs_rq) { /* * 如果se-vruntime是相对值存储时减去了原cfs_rq的min_vruntime * 则需要加上新cfs_rq的min_vruntime进行还原 */ if (se-sum_exec_runtime 0) { // 新任务或首次进入CFS放置在合适位置 se-vruntime cfs_rq-min_vruntime calc_delta_fair(sysctl_sched_latency, se); } }操作步骤与验证# 步骤1使用bpftrace跟踪switched_to_fair调用 cat /tmp/trace_switched_to.bt EOF #!/usr/bin/env bpftrace kprobe:switched_to_fair { printf(switched_to_fair called for pid %d on CPU %d\n, ((struct task_struct *)arg1)-pid, cpu); } kprobe:attach_task_cfs_rq { printf(attach_task_cfs_rq called for pid %d\n, ((struct task_struct *)arg0)-pid); } kprobe:enqueue_entity { printf(enqueue_entity: se%p, vruntime%lu\n, arg1, ((struct sched_entity *)arg1)-vruntime); } EOF sudo bpftrace /tmp/trace_switched_to.bt # 步骤2运行测试程序观察切换过程 sudo chrt -f 50 /tmp/test_task # 步骤3检查CFS运行队列状态 cat /sys/kernel/debug/sched/debug | grep -A 10 cfs_rq5.3 案例三CFS带宽控制在调度类切换中的应用在容器化环境中CFS Bandwidth Control用于限制cgroup的CPU使用量。当任务在不同cgroup或调度类之间迁移时节流状态需要正确处理// 带宽控制相关的辅助函数内核6.x版本 static inline bool task_needs_throttling(struct task_struct *p) { struct cfs_bandwidth *cfs_b task_group(p)-cfs_bandwidth; // 检查任务所属组的运行时是否已耗尽 if (cfs_b-quota RUNTIME_INF) return false; return cfs_b-runtime 0; } static inline void task_throttle_setup(struct task_struct *p) { struct sched_entity *se p-se; // 设置节流标记 se-sched_delayed 1; // 启动节流计时器 start_cfs_bandwidth_timer(); } static inline void task_throttle_cancel(struct task_struct *p) { struct sched_entity *se p-se; // 清除节流标记 se-sched_delayed 0; // 如果任务因节流而延迟调度立即触发调度 if (task_on_rq_queued(p) p-state TASK_RUNNING) { resched_curr(task_rq(p)); } }配置CFS带宽控制并测试# 步骤1创建带带宽限制的cgroup sudo mkdir -p /sys/fs/cgroup/cpu/test_cgroup echo 100000 | sudo tee /sys/fs/cgroup/cpu/test_cgroup/cpu.cfs_quota_us echo 1000000 | sudo tee /sys/fs/cgroup/cpu/test_cgroup/cpu.cfs_period_us # 步骤2启动测试任务并加入cgroup sudo echo $$ | sudo tee /sys/fs/cgroup/cpu/test_cgroup/cgroup.procs # 步骤3运行CPU密集型任务并观察节流情况 stress-ng --cpu 4 --timeout 60 # 步骤4监控节流统计 watch -n 1 cat /sys/fs/cgroup/cpu/test_cgroup/cpu.stat # 步骤5在任务运行期间切换调度策略观察switched_from_fair中的节流处理 sudo chrt -f 50 -p pid_of_stress_ng_thread sudo chrt -o -p 0 pid_of_stress_ng_thread六、常见问题与解答Q1为什么任务从CFS切换到RT后重新切回CFS时vruntime会异常A这通常是由于min_vruntime基准不一致导致的。在switched_from_fair()中任务被detach时会保存相对vruntime减去min_vruntime而在switched_to_fair()中需要正确还原。如果CPU在此期间发生了负载均衡min_vruntime可能已变化导致任务获得不公平的CPU份额。排查方法# 启用调度器调试输出 echo 1 /sys/kernel/debug/sched/verbose # 使用ftrace跟踪vruntime变化 trace-cmd record -e sched:sched_stat_runtime -e sched:sched_switch trace-cmd report | grep pidQ2调度类切换时出现死锁或长时间延迟如何定位A调度类切换涉及rq-lock和p-pi_lock的复杂锁交互。switched_from()回调可能会释放rq-lock而switched_to()通常在持有锁的情况下执行。排查方法# 启用lockdep检测锁问题 CONFIG_LOCKDEPy CONFIG_LOCK_STATy # 查看锁争用统计 cat /proc/lock_stat | head -50 # 使用perf分析调度延迟 perf sched record -- sleep 10 perf sched latencyQ3CFS带宽控制在调度类切换后未正确生效A检查switched_from_fair()和switched_to_fair()中的cfs_bandwidth_used()判断。如果带宽控制未启用CONFIG_CFS_BANDWIDTH未设置或运行时禁用节流逻辑会被跳过。验证方法# 检查内核配置 grep CONFIG_CFS_BANDWIDTH /boot/config-$(uname -r) # 检查运行时启用状态 cat /proc/sys/kernel/sched_cfs_bandwidth_slice_us # 查看任务是否被正确节流 cat /sys/fs/cgroup/cpu/cgroup/cpu.statQ4多核系统中任务在不同CPU之间迁移与调度类切换的交互问题Amigrate_task_rq_fair()处理CPU迁移switched_from/to_fair()处理调度类切换。当两者同时发生时需要确保detach_task_cfs_rq()和attach_task_cfs_rq()的正确调用顺序。排查方法# 监控任务迁移事件 perf trace -e sched:sched_migrate_task -e sched:sched_setscheduler # 检查迁移后的运行队列状态 cat /sys/kernel/debug/sched/debug | grep -E cpu#|cfs_rq|curr七、实践建议与最佳实践7.1 调试技巧使用dynamic debug输出调度类切换详情# 启用fair.c文件的动态调试 echo file kernel/sched/fair.c p /sys/kernel/debug/dynamic_debug/control # 查看dmesg输出 dmesg -w | grep -E switched_from|switched_to|attach|detach通过/proc/sched_debug分析运行队列状态# 提取特定任务的调度信息 grep -A 20 task pid /proc/sched_debug7.2 性能优化建议避免频繁的调度类切换每次切换都涉及红黑树操作和锁竞争高频切换会引入显著开销。合理设置CFS带宽控制参数在容器环境中确保cfs_quota_us和cfs_period_us的比值反映真实的CPU需求避免因节流导致的频繁switched_from/to处理。NUMA感知在NUMA系统中任务迁移时应考虑numa_node与cfs_rq的亲和性减少跨节点内存访问开销。7.3 常见错误规避错误类型表现解决方案vruntime漂移任务切换后CPU份额异常检查attach_task_cfs_rq中的min_vruntime同步负载统计不准确top显示的CPU使用率异常确保update_cfs_rq_load_avg在detach/attach时被调用节流状态残留任务离开受限cgroup后仍被节流验证switched_from_fair中的task_throttle_cancel调用八、总结与应用场景本文深入剖析了Linux CFS调度器中switched_from_fair()和switched_to_fair()的实现机制这两个回调函数是调度类切换时的关键路径。通过detach_task_cfs_rq()和attach_task_cfs_rq()的配对操作内核确保了任务在离开和进入CFS时其调度实体状态、vruntime基准和负载统计的正确性。在实时Linux系统PREEMPT_RT和云原生容器环境中理解这一机制尤为重要实时系统当RT任务临时降级为CFS任务时需要保证平滑过渡避免优先级反转容器平台Kubernetes等编排系统频繁调整任务的cgroup和调度策略正确的状态迁移保证了资源隔离的可靠性建议读者在实际项目中结合ftrace、bpftrace等工具对调度类切换进行动态跟踪深入理解内核调度器的运行时行为。同时关注Linux内核邮件列表中关于调度子系统的最新补丁如2024年提出的per-task throttling改进持续跟踪这一领域的技术演进。

相关文章:

Linux CFS 的 switched_from/switched_to:调度类切换的处理

一、简介在Linux内核的调度子系统中,任务在不同调度类之间切换是一个复杂且关键的操作。当应用程序调用sched_setscheduler()将任务从普通调度策略(SCHED_NORMAL)切换为实时策略(SCHED_FIFO/SCHED_RR),或者…...

从Word2Vec到Attention:用‘讲故事’的方式,轻松理解NLP核心模型演进史

从Word2Vec到Attention:用故事串联NLP模型演进之路 想象一下,你正在教一个刚学会认字的孩子理解"国王-男人女人≈女王"这样的词语关系。这看似简单的语言游戏背后,隐藏着自然语言处理(NLP)技术数十年的智慧结晶。让我们穿越时空&am…...

Windows 11任务栏拖放修复:让消失的拖拽功能重获新生

Windows 11任务栏拖放修复:让消失的拖拽功能重获新生 【免费下载链接】Windows11DragAndDropToTaskbarFix "Windows 11 Drag & Drop to the Taskbar (Fix)" fixes the missing "Drag & Drop to the Taskbar" support in Windows 11. It…...

别再手动删注册表了!一个PowerShell脚本搞定eNSP安装时的WinPcap 4.1.3报错

告别手动清理:用PowerShell自动化解决eNSP与WinPcap的版本冲突 当网络工程师在Windows系统上安装华为eNSP模拟器时,WinPcap 4.1.3的安装报错堪称经典难题。传统解决方案往往要求用户手动操作注册表、系统目录和服务管理器——这种繁琐过程不仅效率低下&a…...

SRE面试必问:K8s生产环境故障排查实战案例解析(附避坑指南)

SRE面试必问:K8s生产环境故障排查实战案例解析(附避坑指南) 在当今云原生技术蓬勃发展的时代,Kubernetes(K8s)已成为企业级容器编排的事实标准。作为Site Reliability Engineer(SRE)…...

RK3588开发板Android系统多屏显示方向动态调整实战

1. RK3588开发板多屏显示基础认知 第一次拿到RK3588开发板时,最让我惊艳的就是它强大的多屏显示能力。这块板子不仅能同时驱动MIPI、HDMI、DP等多种接口的显示屏,还能让每个屏幕独立设置显示方向。在实际项目中,这种特性特别适合数字标牌、互…...

GIS小白必看:如何用GeoServer把普通图片变成可交互地图(附QGIS配准技巧)

GIS入门实战:从普通图片到可交互地图的完整指南 引言:为什么需要将图片转换为可交互地图? 在日常工作中,我们经常会遇到这样的场景:客户提供了一张手绘地图、历史航拍图或是扫描的规划图纸,但这些图片文件…...

CLIP-GmP-ViT-L-14图文匹配工具效果展示:多物体复杂场景中‘主对象’优先匹配

CLIP-GmP-ViT-L-14图文匹配工具效果展示:多物体复杂场景中‘主对象’优先匹配 你有没有遇到过这种情况?一张照片里,有猫、有狗、有沙发、有地毯,背景还有窗外的树。当你问一个AI模型“这张图里有什么”时,它可能会告诉…...

Bilibili-Old:重温经典界面,找回最初的B站体验

Bilibili-Old:重温经典界面,找回最初的B站体验 【免费下载链接】Bilibili-Old 恢复旧版Bilibili页面,为了那些念旧的人。 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Old 你是否怀念那个简洁明了的B站界面?是否…...

在DEBUG环境通过AX、BX 寄存器操作命令理解ALU、ACC的运算逻辑

DEBUG环境下 AX、BX 寄存器操作命令(完整版)12 在DEBUG环境通过AX、BX 寄存器操作命令理解ALU、ACC的运算逻辑 说明:DEBUG是DOS系统下的调试工具,可直接操作CPU内部寄存器(含AX、BX),以下命令…...

告别printf调试!用Telink EVK实时监控BLE芯片变量(8258/8255实战示例)

告别printf调试!用Telink EVK实时监控BLE芯片变量(8258/8255实战示例) 调试嵌入式系统时,开发者常陷入两难:既需要观察程序运行时的内部状态,又受限于传统调试方法的低效。在BLE低功耗场景下,这…...

5步掌握个人数据主权:从微信聊天到AI记忆的完整指南

5步掌握个人数据主权:从微信聊天到AI记忆的完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatM…...

告别SysML v1的混乱:手把手教你用M-Design v2搞定柴油发动机功能分解(Action Usage实战)

从SysML v1到v2的工程革命:柴油发动机功能分解的M-Design v2实践指南 当系统工程师第一次打开SysML v2的规范文档时,那种感觉就像从DOS命令行突然跳进了图形化操作系统时代。作为在汽车行业深耕十余年的系统架构师,我见证过太多团队在SysML v…...

保姆级避坑指南:用ESP-IDF v5.0给虫洞ESP32S3-EYE编译UVC固件,解决屏幕不亮和下载失败

ESP32-S3 UVC摄像头开发实战:从固件编译到屏幕显示的深度排错指南 当你第一次拿到那块印着"ESP32-S3-EYE"的开发板时,脑海中可能已经浮现出无数创意项目——智能门铃、工业检测设备、甚至是一个DIY的视频会议终端。但现实往往比理想骨感得多&a…...

【LabVIEW FPGA图形化】 跨越工具链:在Spartan-6上集成Vivado edf网表的实战解析

1. 当Spartan-6遇上Vivado:工具链冲突的破局之道 遇到Xilinx Spartan-6这类经典FPGA型号时,很多工程师都会头疼一个问题:它只能用老旧的ISE工具链开发,而手头现成的Vivado工程生成的edf网表文件直接导入会报错。去年我在做工业控…...

旅游安全监控:紧急求助与位置追踪的系统

旅游安全监控:紧急求助与位置追踪的系统 随着旅游业的蓬勃发展,游客的安全问题日益受到关注。无论是独自探险的背包客,还是家庭出游的亲子团,都可能面临迷路、突发疾病或意外事故等风险。为此,旅游安全监控系统应运而…...

126. 如何为 Elemental OS Machine 创建网络绑定

Procedure 程序Configuring NIC Teaming for OS Elemental 为操作系统 Elemental 配置 NIC 分组 Overview 概述 This article provides the procedure for configuring NIC Teaming (bonding) in SUSE Elemental OS. It includes an example configuration that can be adjus…...

Mermaid Live Editor终极指南:实时图表编辑与可视化工具深度解析

Mermaid Live Editor终极指南:实时图表编辑与可视化工具深度解析 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-l…...

邻架控制器4C型护套连接器BMJDDL conm/12c(4000)

在煤矿综采工作面液压支架电液控制系统中,邻架控制器之间的级联通信是实现支架群组协同动作的关键。BMJDDL conm/12c(4000) 是一款专为邻架通信设计的12芯钢丝编织橡胶护套连接器,其长度4000mm(4米)适配液压支架的标准中心距&…...

ncmdump终极指南:3步解锁网易云音乐NCM格式,实现音乐自由播放

ncmdump终极指南:3步解锁网易云音乐NCM格式,实现音乐自由播放 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾在网易云音乐下载了心爱的歌曲,却发现在车载音响、其他播放器或设备上无法播…...

语音转文字还在手动操作?3分钟学会AsrTools的完整解决方案

语音转文字还在手动操作?3分钟学会AsrTools的完整解决方案 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into accur…...

如何让微信聊天记录成为你的数字记忆银行?WeChatMsg终极指南

如何让微信聊天记录成为你的数字记忆银行?WeChatMsg终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we…...

不止于蓝牙!挖掘杰理AC632N的隐藏技能:SPP/LE与CDC双模通信实战,一个设备搞定所有调试

杰理AC632N双模通信实战:SPP/LE与CDC的协同设计艺术 当一块开发板能同时完成蓝牙数据透传和有线调试,你会用它做什么?杰理AC632N这颗国产芯片的潜力远超多数开发者的想象。今天我们不谈基础功能,而是聚焦一个真实开发场景&#x…...

别急着升Unity 2022!手把手教你为Unity 2021.3项目配置专属的Java 11和Gradle 7.5环境

深度定制Unity 2021.3的Android构建环境:Java 11与Gradle 7.5实战指南 当Google Play强制要求应用适配Android 14(API Level 34)时,许多仍在使用Unity 2021.3 LTS的开发者面临一个棘手问题:如何在不升级Unity版本的前…...

React Fiber 优先级队列实现

React Fiber优先级队列实现解析 React Fiber是React 16引入的核心架构,旨在优化渲染性能并支持任务优先级调度。其中,优先级队列的实现是关键机制之一,它确保高优先级任务(如用户交互)能快速响应,而低优先…...

3步实现知网文献批量下载:CNKI-download自动化工具完整指南

3步实现知网文献批量下载:CNKI-download自动化工具完整指南 【免费下载链接】CNKI-download :frog: 知网(CNKI)文献下载及文献速览爬虫 (Web Scraper for Extracting Data) 项目地址: https://gitcode.com/gh_mirrors/cn/CNKI-download 在学术研究的道路上&…...

Spring Boot Actuator 监控扩展

Spring Boot Actuator 监控扩展:提升应用可观测性的利器 在现代微服务架构中,应用的监控与运维至关重要。Spring Boot Actuator 作为Spring Boot生态的核心组件,为开发者提供了丰富的生产级监控端点,帮助实时掌握应用的健康状态、…...

Zemax物理光学传播(POP)入门:从高斯光束到衍射效应的实战解析

Zemax物理光学传播(POP)实战指南:从参数设置到衍射效应分析 在光学设计领域,几何光学和物理光学就像一枚硬币的两面。前者帮助我们快速勾勒出光路的基本轮廓,而后者则揭示了光波传播中那些精妙的波动特性。Zemax作为行业标杆的光学设计软件&a…...

Wan2.1 VAE效果案例:基于潜空间算术的“微笑编辑”真实演示

Wan2.1 VAE效果案例:基于潜空间算术的“微笑编辑”真实演示 1. 引言:当AI学会“微笑” 你有没有想过,给一张照片里的人换个表情,比如让他从面无表情变成面带微笑,需要几步? 如果是以前,你可能…...

VCS仿真中xprop选项的实战配置指南:从基础到高级用法

VCS仿真中xprop选项的实战配置指南:从基础到高级用法 在芯片设计验证领域,X态传播仿真是确保设计可靠性的关键环节。VCS作为业界主流的仿真工具,其xprop选项的灵活配置直接影响验证效率和准确性。本文将带您从基础配置到高级应用,…...