🐧 第四章 进程调度器
📄 一句话概括

一份 ps aux 能读出五件事:谁起的、什么状态、有没有被降权、吃多少资源、累计真干了多少活。%CPU 与 TIME+ 必须一起看——一个看当下,一个看累计。

📝 本节和前面几节的关系

4.18 讲懂了睡眠,这一节回到真机:把前面讲的所有概念,落到 ps 与 /proc 的那几列数字上。

一、五个字段,五种判断

PID/PPID:自己的号、爹的号。读它能画出进程树,知道是谁起的。 STAT:状态码(4.6 那五个字母)。在跑、在等、还是僵尸。 NI/PRI:nice 值与显示优先级。是不是被人为调过权。 %CPU/%MEM:当下占用比例。谁在吃资源。 TIME+:累计占用 CPU 的时间。这才是【真干了多少活】的度量。

二、%CPU 与 TIME+ 为什么要一起看

%CPU 高、TIME+ 不涨:进程在抖——不停地起来又睡,或者在等锁。 TIME+ 一直涨、%CPU 不高:它被分摊到很多核上(多线程),或者它是间歇性地跑。 两个都高:真在烧 CPU,这是最明确的情况。 两个都低但服务很慢:瓶颈根本不在这个进程上——去查下游、查磁盘、查网络。

三、/proc 里那些数字的来历

/proc/<pid>/stat:一长串数字,状态、父子号、CPU 时间、内存、优先级都在里面。ps 读的就是它。 /proc/<pid>/status:同上的可读版,推荐先看这个。 /proc/<pid>/fd:打开的文件的软链接。排查【文件被谁占着】就看这里。 /proc/meminfo:整机内存账本。/proc/stat:整机 CPU 账本。 共同点:不占磁盘、读一次生成一次。ps、top、free 不过是【读文件 + 排版】。

四、从 ps 到结论的一条路

第一步,看谁在吃 CPU:ps aux --sort=-%cpu | head。 第二步,看它是什么状态:R 是 CPU 密集,S 是在等,D 是卡在硬件。 第三步,看它的累计时间:TIME+ 很小但 %CPU 很高 → 说明它刚起来或者一直在抖。 第四步,看它打开了什么:ls -l /proc/<pid>/fd,很多时候答案就在那些文件里(比如一个巨大的日志、一个慢的 socket)。 这四步比任何监控面板都快,而且不用装任何东西。

五、动手 Demo:现实中的进程——一份 ps 输出能读出什么

把 ps 的关键字段列成表,再补一张 /proc 文件的来历表。最后把你的机器自己的几个数打出来,让你知道这些抽象在哪。

import os, platform

FIELDS = {
    "PID/PPID": "自己的号、爹的号 -> 进程树",
    "STAT":     "状态码 -> 在跑、在等、还是僵尸",
    "NI/PRI":   "nice 与显示优先级 -> 有没有被降权",
    "%CPU/%MEM": "当下占用 -> 谁在吃资源",
    "TIME+":    "累计 CPU 时间 -> 真干了多少活",
}

print(platform.system(), os.getpid(), os.cpu_count())

实跑输出:

--------------------------------------------------------------------
现实中的进程——一份 ps 输出能读出什么
--------------------------------------------------------------------
① 我这台机器上能看到的进程信息

  字段            含义                    读它能判断什么
  -------------------------------------------------------------
  PID / PPID      自己的号、爹的号        进程树、谁起的
  STAT            状态码                  在跑、在等、还是僵尸
  NI / PRI        nice 值与显示优先级     是不是被降过权
  %CPU / %MEM     占用比例                谁在吃资源
  TIME+           累计占用 CPU 时间       是真干活还是占着不动

      **这台机器的系统**              Windows
      当前进程号                    2032
      逻辑核数                      8

  **`%CPU` 与 `TIME+` 要一起看**:%CPU 高但 TIME+ 不涨,说明在抖;
  TIME+ 一直涨而 %CPU 不高,说明**它被分摊在很多核上**(多线程)。

② /proc 里那些数字的来历

  文件                   里面是什么                   谁写的
  -----------------------------------------------------------------
  /proc/<pid>/stat       状态、时间、内存等一长串     内核现场生成
  /proc/<pid>/status     同上的可读版                 内核现场生成
  /proc/<pid>/fd         打开的文件(软链接)         内核现场生成
  /proc/meminfo          整机内存账本                 内核现场生成

  **它们的共同点:不占磁盘、读写就是一次内核查询。**
  **`ps`、`top`、`free` 这些命令,本质都是【读几个文件、排一下版】。**

这五个字段合起来,就是【一个进程的全部画像】:身份、状态、权限、当下占用、累计工作量。 %CPU 与 TIME+ 一定要一起看:只看一个,很容易得出相反结论。 /proc 那些文件不占磁盘,读它们等于向内核提问。这就是为什么 ps 能做到【不装任何东西就看到一切】。

📋 一条命令代替一堆工具:ps -eo pid,ppid,stat,ni,pcpu,pmem,etime,time,comm --sort=-pcpu | head -15。这九列基本覆盖了排查需要的全部信息。

30 秒实验

  1. ps -eo pid,ppid,stat,pcpu,time,comm --sort=-pcpu | head——看谁在烧 CPU。
  2. ls -l /proc/<pid>/fd——看一个进程打开了哪些文件(常用于查【磁盘为什么满】与【端口被谁占】)。
  3. cat /proc/<pid>/status | head -12——可读版的状态、内存、线程数。

常见误区

  1. 【%CPU 就是它占了多少 CPU】。它是【采样区间内的平均】。多核机器上可以超过 100%(多线程)。
  2. 【TIME+ 是它运行了多久】。那是【占 CPU 的累计时间】,不是墙上时间。一个跑了三天的服务,TIME+ 可能只有几分钟。
  3. 【ps 看到的是实时数据】。它是【读 /proc 时的快照】。要趋势得反复采样或用 vmstat/top。
自测三问(点开对答案) 1. ps 里哪五个字段最有用?各能判断什么? —— PID/PPID(进程树)、STAT(状态)、NI/PRI(权限)、%CPU/%MEM(当下占用)、TIME+(累计工作量)。 2. 为什么 %CPU 与 TIME+ 要一起看? —— %CPU 高而 TIME+ 不涨说明在抖;TIME+ 涨而 %CPU 不高说明吃多核或间歇跑。**单看一个容易下错结论。** 3. `ps`、`top`、`free` 本质是什么? —— **读 /proc 下的文件再排版**。那些文件不占磁盘,读一次由内核生成一次。

相关笔记