You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下如何排查两个检查点间运行的任务与进程耗时问题

void main() {

    //some code
    printf(" hi \n");
   
    checkpoint1(); // <-------- checkpoint1

    //some Code with no dependency on other program/task or HW IO

    checkpoint2(); // <-------- checkpoint2

    printf(" test end \n");

    //some code

    return;

}
Linux下排查checkpoint1与checkpoint2间耗时过长的方案

一、系统工具类方案(适合手动/临时排查)

1. perf 性能分析工具

perf是Linux内核自带的性能分析框架,可精准捕获这段时间内的CPU调度与进程运行情况:

  • 操作步骤:
    1. 程序运行到checkpoint1时,在终端执行:perf record -a -e sched:sched_switch -g -- sleep <预估耗时>(若无法预估耗时,可在checkpoint2触发后立即按Ctrl+C停止perf)
    2. 执行perf script分析捕获的日志,可看到所有CPU上的进程切换事件,以及每个进程/线程的运行时间段,通过时间戳对比可计算出各进程在这段时间内的CPU占用时长。
  • 补充:若需要更详细的CPU使用统计,可执行perf stat -a -I 1000(每隔1秒输出一次全系统CPU使用统计),结合程序checkpoint1/checkpoint2的时间戳,定位对应时间段的高占用进程。

2. pidstat 进程统计工具

pidstat可周期性输出所有进程/线程的CPU、内存等资源使用情况,适合定位突发的CPU占用:

  • 操作步骤:
    1. 程序启动前执行:pidstat -u -t -d 1 > pidstat.log(每隔1秒输出一次进程/线程的CPU、IO统计,结果写入日志)
    2. 程序运行完checkpoint2后停止pidstat,根据日志中记录的时间戳,筛选checkpoint1到checkpoint2的时间段,查看各进程的%CPU列和UTIME/STIME列的变化,即可得到这段时间内各进程的CPU运行时长。

3. ftrace 内核跟踪工具

ftrace是内核级别的跟踪框架,可精准捕获进程调度的细节:

  • 操作步骤:
    1. 挂载tracefs:mount -t tracefs nodev /sys/kernel/tracing
    2. 启动跟踪:echo sched_switch > /sys/kernel/tracing/set_event,echo 1 > /sys/kernel/tracing/tracing_on
    3. 程序运行过checkpoint2后,停止跟踪:echo 0 > /sys/kernel/tracing/tracing_on
    4. 查看日志:cat /sys/kernel/tracing/trace,日志中会记录每个CPU上的进程切换事件,包含进程PID、名称、切换时间,可通过这些数据计算各进程的运行时长。

二、编程式API方案(适合集成到程序自动排查)

1. 读取/proc文件系统

/proc是内核暴露给用户态的虚拟文件系统,可直接读取进程与CPU的运行统计数据:

  • 实现思路:
    1. 在checkpoint1()中,遍历/proc目录下的所有PID文件夹,读取每个进程的/proc/<pid>/stat文件,提取第14、15个字段(utime:用户态运行时间,stime:内核态运行时间,单位为jiffies),同时读取/proc/stat中各CPU的总运行时间,保存为初始状态。
    2. 在checkpoint2()中,重复上述读取操作,计算每个进程utime+stime的差值,以及CPU总时间的差值,即可得到这段时间内各进程占用CPU的时长占比与绝对时长。
  • 注意:若需要跟踪线程,需遍历/proc/<pid>/task/<tid>目录,读取每个线程的stat文件。

2. perf_event_open API

这是perf工具的底层内核API,可在程序中直接创建性能事件,捕获调度数据:

  • 核心步骤:
    1. 使用perf_event_open()函数打开PERF_TYPE_TRACEPOINT类型的事件,对应tracepoint:sched:sched_switch事件(事件ID可通过/sys/kernel/tracing/events/sched/sched_switch/id获取),设置PERF_FLAG_FD_CLOEXEC等标志。
    2. 在checkpoint1()中启动事件采样(ioctl(fd, PERF_EVENT_IOC_ENABLE, 0)),在checkpoint2()中停止采样(ioctl(fd, PERF_EVENT_IOC_DISABLE, 0))。
    3. 通过read()函数读取捕获的事件数据,解析出进程切换的时间戳、进程PID/名称等信息,计算各进程的运行时长。
  • 代码示例片段:
#include <linux/perf_event.h>
#include <sys/ioctl.h>
#include <unistd.h>

int perf_fd;

void checkpoint1() {
    struct perf_event_attr attr = {0};
    attr.type = PERF_TYPE_TRACEPOINT;
    attr.config = /* 替换为sched_switch的tracepoint ID */;
    attr.size = sizeof(attr);
    attr.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_TIME;
    attr.sample_period = 1;
    attr.wakeup_events = 1;

    perf_fd = perf_event_open(&attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
    ioctl(perf_fd, PERF_EVENT_IOC_ENABLE, 0);
}

void checkpoint2() {
    ioctl(perf_fd, PERF_EVENT_IOC_DISABLE, 0);
    // 读取并解析perf_fd中的事件数据
    char buf[4096];
    ssize_t n = read(perf_fd, buf, sizeof(buf));
    // 解析逻辑省略,需根据perf事件格式解析进程切换信息
    close(perf_fd);
}

内容的提问来源于stack exchange,提问作者Henry Leong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:35:20