Linux下如何监控进程I/O等待耗时及磁盘I/O线程利用率?
先给你解惑为啥之前的方法不行:你看的utime/stime确实不包含I/O等待时间——因为iowait属于进程阻塞等待外部IO完成的状态,既不在用户态跑代码也不在内核态干活,所以根本不会算到那两个字段里。不过别担心,有好几种可靠的方法能拿到你要的线程级I/O等待数据:
方法1:直接读取proc文件系统的线程统计字段
内核从2.6.18版本开始就支持了任务延迟统计(大部分发行版默认都开了这个内核选项,叫CONFIG_TASK_DELAY_ACCT),每个线程的/proc/[pid]/task/[tid]/stat文件里藏着个关键字段:
- 第41个字段
delayacct_blkio_ticks:记录了该线程因为阻塞IO(比如等待磁盘读写完成)消耗的总时间,单位是jiffies(通常1个jiffies等于10ms,取决于内核配置的HZ值)。
你可以写个简单的脚本定期读取这个值,两次读取的差值就是这段时间内该线程的IO等待耗时。比如:
# 假设目标进程PID是1234,线程TID是12345 prev_blkio=$(awk '{print $41}' /proc/1234/task/12345/stat) sleep 5 curr_blkio=$(awk '{print $41}' /proc/1234/task/12345/stat) wait_ms=$(( (curr_blkio - prev_blkio) * 10 )) echo "5秒内该线程IO等待耗时:${wait_ms}ms"
方法2:用pidstat做线程级IO统计
pidstat是sysstat工具集里的实用工具,专门用来做进程/线程的资源统计,非常适合你的场景:
- 用
-t参数显示线程级数据,-p <pid>指定目标进程,-d聚焦IO相关统计,-w可以查看等待状态的时间占比:
# 每隔1秒输出一次目标进程(PID=1234)的所有线程IO统计,共输出5次 pidstat -t -p 1234 -d -w 1 5
输出里的%wait字段就是线程处于等待状态(包括IO等待)的时间占比,kB_rd/s/kB_wr/s能辅助看线程的IO负载,结合起来就能判断线程是不是在等IO。
方法3:用iotop实时监控线程IO状态
iotop是交互式的IO监控工具,能直观看到每个线程的IO活动和等待情况:
- 启动时加
-t显示线程,-p <pid>过滤目标进程:
iotop -t -p 1234
你会看到每个线程的IO>列(IO等待占比),还有DISK READ/DISK WRITE的速率,能实时观察哪些IO线程在等待数据、等待时长占比多少。
方法4:用perf做更精细的分析
如果需要更深入的分析(比如到底在等哪些IO操作),可以用perf工具:
- 实时统计单个线程的IO请求情况,间接算出等待时长:
perf stat -t 12345 -e block:block_rq_issue,block:block_rq_complete sleep 10
这个会统计10秒内该线程发起的IO请求数和完成数,结合时间就能算出平均等待时长,还能进一步用perf record追踪具体的IO调用栈,定位到底是哪些操作在拖慢线程。
总结一下,如果你要做自动化监控,优先用proc的delayacct_blkio_ticks字段或者pidstat的脚本化输出;如果是实时排查,iotop最直观;深入分析就上perf。
内容的提问来源于stack exchange,提问作者Jason R

