【ROS/ROS2与实时Linux系列】第四篇 内核调度器优化:CFS、SCHED_FIFO、SCHED_RR在实时场景
本文详细介绍了Linux内核调度器优化在ROS/ROS2实时系统中的关键作用。重点解析了完全公平调度器(CFS)和实时调度器(SCHED_FIFO/SCHED_RR)的特性与适用场景,并提供了实时Linux环境搭建的详细步骤。通过实际案例展示了如何配置实时调度策略(包括命令行和代码实现),以及优化CFS参数的方法。文章还针对常见问题提供解决方案,并给出性能优化建议,如减少上下文切换、合理分配CPU
一、简介:为什么调度器优化对 ROS/ROS2 至关重要?
在 ROS/ROS2 应用中,无论是机器人导航、工业自动化控制还是自动驾驶,实时性都是关键需求。例如,自动驾驶车辆需要在极短时间内对传感器数据进行处理并做出决策,以确保安全。Linux 内核调度器负责分配 CPU 时间给不同进程和线程,其配置直接影响实时任务的执行效率和响应速度。掌握调度器优化,可以帮助开发者确保关键任务及时执行,提升系统的整体性能和可靠性。
二、核心概念:调度器的特性与术语
2.1 完全公平调度器(CFS)
-
特性:CFS 是 Linux 默认的调度器,旨在公平地分配 CPU 时间给所有进程。它通过虚拟运行时间(vruntime)来衡量进程的运行时间,确保每个进程都能获得公平的 CPU 时间。
-
适用场景:适用于大多数通用计算任务,但在实时任务中可能不够灵活。
2.2 实时调度器(SCHED_FIFO 和 SCHED_RR)
-
SCHED_FIFO:
-
特性:实时任务按优先级顺序运行,高优先级任务优先执行。一旦任务开始运行,它将一直运行直到完成或主动放弃 CPU。
-
适用场景:适用于对实时性要求极高的任务,如机器人控制、传感器数据处理。
-
-
SCHED_RR:
-
特性:与 SCHED_FIFO 类似,但每个任务运行一段时间后会被挂起,等待下一次调度。这有助于防止高优先级任务长时间占用 CPU。
-
适用场景:适用于需要多个实时任务共享 CPU 的场景,如多线程的实时数据处理。
-
2.3 相关术语
-
vruntime:虚拟运行时间,CFS 用来衡量进程的运行时间。
-
nice 值:进程的优先级,值越小优先级越高。默认值为 0,范围从 -20(最高优先级)到 19(最低优先级)。
-
实时优先级:实时任务的优先级,范围从 1 到 99,值越大优先级越高。
三、环境准备:搭建实时 Linux 环境
3.1 硬件需求
-
CPU:多核处理器(建议至少 4 核)
-
内存:至少 4 GB RAM
-
存储:SSD 硬盘
3.2 软件需求
-
操作系统:Ubuntu 20.04 或更高版本(推荐使用实时内核)
-
开发工具:GCC、CMake、Git
-
ROS/ROS2:ROS Noetic 或 ROS2 Foxy
3.3 安装实时内核
-
安装实时内核(推荐使用 PREEMPT_RT 内核):
sudo apt update
sudo apt install linux-headers-$(uname -r) linux-image-$(uname -r)
sudo apt install linux-headers-$(uname -r)-realtime linux-image-$(uname -r)-realtime
-
重启并选择实时内核:
sudo reboot
重启后,选择实时内核启动。
3.4 安装 ROS/ROS2
-
安装 ROS Noetic:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros.list'
sudo apt install ros-noetic-desktop-full
source /opt/ros/noetic/setup.bash
-
安装 ROS2 Foxy:
sudo apt update && sudo apt install -y curl gnupg2 lsb-release
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros2/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/ros2.list
sudo apt update && sudo apt install -y ros-foxy-desktop
source /opt/ros/foxy/setup.bash
四、应用场景:机器人实时控制
在机器人实时控制场景中,关键任务如传感器数据处理、运动控制算法需要在极短时间内完成,以确保机器人的响应速度和精度。通过优化内核调度器,可以确保这些任务及时获得 CPU 资源,避免因调度延迟导致的控制误差。
五、实际案例与步骤:配置实时调度策略
5.1 查看当前调度策略
-
查看当前进程的调度策略:
chrt -p <pid>
-
查看当前系统的调度策略:
cat /proc/sched_debug
5.2 配置实时任务
5.2.1 使用 chrt 设置实时优先级
-
设置 SCHED_FIFO:
chrt -f -p 99 <pid>
-
设置 SCHED_RR:
chrt -r -p 99 <pid>
5.2.2 在代码中设置实时优先级
-
C++ 示例:
#include <sched.h>
#include <iostream>
void set_realtime_priority(int priority) {
struct sched_param param;
param.sched_priority = priority;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
}
int main() {
set_realtime_priority(99);
std::cout << "Running with real-time priority 99" << std::endl;
while (true) {
// Real-time task
}
return 0;
}
-
Python 示例:
import os
import ctypes
def set_realtime_priority(priority):
libc = ctypes.CDLL('libc.so.6')
param = ctypes.c_int(priority)
if libc.sched_setscheduler(0, 1, ctypes.byref(param)) == -1:
raise OSError("sched_setscheduler failed")
if __name__ == "__main__":
set_realtime_priority(99)
print("Running with real-time priority 99")
while True:
pass
5.3 配置 CFS 调度器
-
调整 CFS 的时间片:
echo 1000 > /sys/kernel/mm/cfs/rt_runtime_us
-
调整 CFS 的调度周期:
echo 100000 > /sys/kernel/mm/cfs/rt_period_us
5.4 验证调度策略
-
运行实时任务:
./realtime_task
-
监控任务调度:
top -H -p <pid>
六、常见问题与解答
6.1 如何确定任务是否需要实时调度?
-
问题:如何判断一个任务是否需要实时调度?
-
解答:实时任务通常需要在极短时间内完成,对延迟敏感。例如,传感器数据处理、运动控制算法等。可以通过任务的响应时间要求来判断是否需要实时调度。
6.2 如何设置实时优先级?
-
问题:如何设置实时任务的优先级?
-
解答:可以使用
chrt命令或在代码中调用sched_setscheduler函数。例如,chrt -f -p 99 <pid>将进程设置为 SCHED_FIFO,优先级为 99。
6.3 如何验证调度策略是否生效?
-
问题:如何验证调度策略是否生效?
-
解答:可以使用
top -H -p <pid>查看任务的调度情况。如果任务的优先级和调度策略正确设置,任务将按预期运行。
6.4 如何调整 CFS 调度器参数?
-
问题:如何调整 CFS 调度器参数?
-
解答:可以通过写入
/sys/kernel/mm/cfs/rt_runtime_us和/sys/kernel/mm/cfs/rt_period_us文件来调整 CFS 的时间片和调度周期。
七、实践建议与最佳实践
7.1 调试技巧
-
使用
strace跟踪系统调用:
strace -p <pid>
-
使用
perf分析性能:
perf
record -g -p <pid>
7.2 性能优化
减少上下文切换:
尽量减少实时任务的上下文切换,提高任务的连续运行时间。
·合理分配 CPU 核心:
使用 `taskset` 命令将实时任务固定在特定的 CPU 核心上,减少 CPU 亲和性切换带来的延迟。
7.3 常见错误的解决方案
·实时任务被挂起:
检查任务的优先级是否过高,导致其他任务无法运行。适当调整优先级。
·任务响应时间过长:
检查任务是否被其他高优先级任务抢占,调整任务的调度策略。
八、总结与应用场景
通过本文的介绍,我们深入解析了 Linux 内核调度器(CFS、SCHED_FIFO、SCHED_RR)的特性,并指导了如何在实时 Linux 环境中为 ROS/ROS2 进程配置合适的调度策略与优先级。掌握这些技能,可以帮助开发者确保关键任务及时执行,提升系统的整体性能和可靠性。
在实际应用中,例如机器人实时控制、自动驾驶、工业自动化等场景,通过优化内核调度器,可以显著提升系统的实时性和稳定性。希望本文能够帮助读者在实际项目中应用所学知识,优化系统性能,确保任务的高效执行。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)