为什么top或者htop的状态总是"R"(运行)?

Why is the status of top or htop always "R" (running)?

tophtop是监控进程和计算机资源的常用工具,但为什么top本身的状态总是R(在[= top) 的 18=] 列?例如,这里是 top 命令的屏幕截图:

top - 12:42:33 up  2:48,  1 user,  load average: 0,11, 0,17, 0,17
Tasks: 319 total,   1 running, 318 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1,1 us,  0,1 sy,  0,0 ni, 98,8 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
MiB Mem :  15968,5 total,   4031,8 free,   2196,1 used,   9740,7 buff/cache
MiB Swap: 122069,0 total, 122069,0 free,      0,0 used.  13325,4 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   2264 xxxxxx    20   0 2784640 320344 184092 S   6,0   2,0   9:14.83 Web Content
   2195 xxxxxx    20   0 3996144 481160 197788 S   2,7   2,9   7:46.13 firefox
   1704 root      20   0  227712 101204  82140 S   1,3   0,6   3:26.54 Xorg
   2993 xxxxxx    20   0  817416  54452  41724 S   1,0   0,3   0:04.27 gnome-terminal-
   1856 xxxxxx    20   0 4521152 385832 123440 S   0,7   2,4   2:39.79 gnome-shell
   1202 root     -51   0       0      0      0 S   0,3   0,0   0:52.07 irq/44-nvidia
   5048 xxxxxx    20   0   11980   3888   3132 R   0,3   0,0   0:00.12 top
      1 root      20   0  167972  11864   8480 S   0,0   0,1   0:03.91 systemd
      2 root      20   0       0      0      0 S   0,0   0,0   0:00.00 kthreadd
      3 root       0 -20       0      0      0 I   0,0   0,0   0:00.00 rcu_gp
      4 root       0 -20       0      0      0 I   0,0   0,0   0:00.00 rcu_par_gp
      6 root       0 -20       0      0      0 I   0,0   0,0   0:00.00 kworker/0:0H-kblockd
      9 root       0 -20       0      0      0 I   0,0   0,0   0:00.00 mm_percpu_wq
     10 root      20   0       0      0      0 S   0,0   0,0   0:00.09 ksoftirqd/0
     11 root      20   0       0      0      0 I   0,0   0,0   0:01.49 rcu_sched
     12 root      rt   0       0      0      0 S   0,0   0,0   0:00.02 migration/0
     13 root     -51   0       0      0      0 S   0,0   0,0   0:00.00 idle_inject/0

topprocps/top)的源代码中,它从文件/proc/<pid>/stat获取进程状态,而top的状态,对于大多数时间,是S(休眠)如果用下面的命令连续打印:

watch -n.1 "cat /proc/<top-pid>/stat | grep -o \"[S|R]\""

嗯...如果你是运行top(或htop),并且top(或htop)得到它自己的状态来自/proc/self/stat...然后它必须是运行,否则它怎么可能获得它的状态同时不是 运行?进程正在读取其自身状态的唯一事实意味着在读取时状态必须是 运行。

如果你愿意,你也可以用其他程序试试这个:

$ cat /proc/self/stat
32482 (cat) R ...
$ head /proc/self/stat
32491 (head) R ...
$ tail /proc/self/stat
32497 (tail) R ...
$ less /proc/self/stat
32503 (less) R ...

这是所谓的 observer effect popularized by the physicist Werner Heisenberg 的一个例子:他说观察系统的行为不可避免地会改变它的状态。因此,当 top/htop 观察到他们正常的状态时,他们看不到自己在睡觉 ;-)