列出进程
目标
完成本节内容后,你能够获得系统上运行的程序的相关信息,以确定状态、资源使用和所有权,这样你就可以控制它们。
进制的定义
进程是一个已启动的可执行程序的运行实例。一个进程包括:
- 一个分配的内存地址空间
- 安全属性,包括所有权凭证和特权
- 一个或多个程序代码的执行线程
进程状态
一个进程的环境包括:
- 本地变量和全局变量
- 当前调度上下文
- 已分配的系统资源,如文件描述符和网络端口等
一个现有的(父进程)进程复制自己的地址空间(fork)以创建一个新的(子进程)结构。每个新进程都被分配了一个唯一的进程ID(PID),用于跟踪和安全。PID和父进程的进程ID(PPID)是新进程环境的元素。任何进程都可以创建一个子进程。所有的进程都是第一个系统进程的子进程,即Red Hat Enterprise Linux 8系统上的systemd的子进程。
通过fork例程,子进程继承了安全身份、先前和当前的文件描述符、端口和资源权限、环境变量以及程序代码。然后,子进程可以执行自己的程序代码。通常情况下,父进程在子进程运行时,父进程会休眠,当子进程完成时,设置一个请求(等待)信号。退出时,子进程已经关闭或丢弃了它的资源和环境。唯一剩下的资源,称为僵尸,是进程表中的一个条目。当子进程退出时,父进程在子进程退出时发出唤醒的信号,清理进程表中的子进程条目,从而释放出子进程的最后一个资源。然后,父进程继续执行自己的程序代码。
描述进程状态
在多任务操作系统中,每个CPU(或CPU核心)可以在一个时间点上处理一个进程。当一个进程运行时,它对CPU时间和资源分配的直接需求会发生变化。进程被分配了一个状态,这个状态会随着情况的变化而变化。
Linux进程状态如上图所示,如下表所示:
名称 | 标志 | 内核定义的状态名称和描述 |
---|---|---|
Running | R | TASK_RUNNING:进程正在CPU上执行或等待运行。进程可以是执行用户例程或内核例程(系统调用),也可以在运行(或可运行)状态时处于队列和准备状态。 |
Sleeping | S | TASK_INTERRUPTIBLE:进程正在等待某些条件:硬件请求、系统资源访问或信号。当事件或信号满足条件时,进程返回到运行状态。 |
D | TASK_UNINTERRUPTIBLE:该进程也是Sleeping,但与S状态不同,不响应信号。仅在进程中断可能导致设备状态不可预测时使用。 | |
K | TASK_KILLABLE:与不间断的D状态相同,但修改后允许一个等待的任务响应应该被杀死的信号(完全退出)。实用程序经常将可杀进程显示为D状态。 | |
I | TASK_REPORT_IDLE:状态D的一个子集,内核在计算负载平均时不计算这些进程。用于内核线程。标志TASK_UNINTERRUPTABLE和TASK_NOLOAD被设置。类似于TASK_KILLABLE,也是状态D的一个子集,它接受致命信号。 | |
Stopped | T | TASK_STOPPED:进程已被停止(暂停),通常由用户或其他进程发出信号。该进程可以继续进行(恢复)由另一个信号返回运行。 |
T | TASK_TRACED:正在调试的进程也被暂时停止,并共享同一个T状态标志。 | |
Zombie | Z | EXIT_ZOMBIE:一个子进程在退出时向其父进程发出信号。除了进程标识(PID)外,所有的资源都被释放。 |
X | EXIT_DEAD:当父进程清理(收割)剩余的子进程结构时,该进程现在被完全释放。这种状态永远不会在进程列表工具中被观察到。 |
为什么进程状态很重要?
在排除系统故障时,了解内核如何与进程通信以及进程之间的通信方式是非常重要的。在进程创建时,系统会给进程分配一个状态。top命令的S列或ps的STAT列显示了每个进程的状态。在一个CPU系统中,一次只能运行一个进程。有可能看到多个进程的状态为R,但不是所有的进程都会连续运行,有的进程会处于状态等待状态。
[user@host ~]$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 244344 13684 9024 S 0.0 0.7 0:02.46 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
...output omitted...
[user@host ~]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
...output omitted...
root 2 0.0 0.0 0 0 ? S 11:57 0:00 [kthreadd] student 3448 0.0 0.2 266904 3836 pts/0 R+ 18:07 0:00 ps aux
...output omitted..
进程可以使用信号暂停、停止、恢复、终止和中断。信号在本章后面会详细讨论。信号可以被其他进程、内核本身或登录到系统的用户使用。
查看进程
ps命令用于列出当前进程。它可以提供详细的进程信息,包括:
- 用户标识(UID),决定了进程的权限
- 不同的进程识别码(PID)
- 已消耗的CPU和实际时间
- 进程分配了多少内存
- stdout流的位置,被称为控制终端
- 当前的进程状态
Linux版本的ps支持三种选项格式:
UNIX (POSIX)选项,可以分组,并且必须在前面加上破折号。
BSD选项,可以进行分组,不使用破折号。
GNU 长选项,前面带有两个破折号。例如,ps -aux与ps aux不同。
也许最常用的一组选项aux显示所有过程,包括没有控制终端的进程。 较长的清单(选项lax)提供了更多的技术细节,但可以通过避免用户名查找来更快地显示。 相似的UNIX语法使用-ef选项显示所有进程。
[user@host ~]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.1 51648 7504 ? Ss 17:45 0:03 /usr/lib/systemd/ syst root 2 0.0 0.0 0 0 ? S 17:45 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 17:45 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 17:45 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 17:45 0:00 [migration/0]
...output omitted...
[user@host ~]$ ps lax
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
4 0 1 0 20 0 51648 7504 ep_pol Ss ? 0:03 /usr/lib/ systemd/
1 0 2 0 20 0 0 0 kthrea S ? 0:00 [kthreadd]
1 0 3 2 20 0 0 0 smpboo S ? 0:00 [ksoftirqd/0]
1 0 5 2 0 -20 0 0 worker S< ? 0:00 [kworker/0:0H]
1 0 7 2 -100 - 0 0 smpboo S ? 0:00 [migration/0]
...output omitted...
[user@host ~]$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 17:45 ? 00:00:03 /usr/lib/systemd/systemd -switched-ro root 2 0 0 17:45 ? 00:00:00 [kthreadd]
root 3 2 0 17:45 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 17:45 ? 00:00:00 [kworker/0:0H]
root 7 2 0 17:45 ? 00:00:00 [migration/0]
...output omitted...
默认情况下,没有选项的ps会选择所有与当前用户具有相同有效用户ID(EUID)的进程,并且与ps被调用的同一终端相关联。
括号内的进程(通常在列表的顶部)是计划的内核线程。
僵尸被列为退出或消亡。
ps的输出显示一次。使用top进行动态更新的过程显示。
ps可以以树形格式显示,因此可以查看父进程和子进程之间的关系。
默认的输出是按进程ID号排序。乍一看,这似乎是按时间顺序排列的。但是,内核会重用进程ID,所以顺序没有看起来那么有条理。要进行排序,请使用 -O 或 --sort 选项。显示顺序与系统进程表的顺序相匹配,当进程死亡和新的进程被创建时,系统进程表会重用表行。输出可能会按时间顺序显示,但除非使用明确的 -O 或 --sort选项,否则不能保证输出是按时间顺序显示的。
控制作业
目标
完成本节后,您应该能够使用Bash作业控制来管理从同一终端会话启动的多个进程。
描述作业和会话
作业控制是shell的一个功能,它允许一个shell实例运行和管理多个命令。
一个作业与在shell提示符输入的每个管道相关联。该管道中的所有进程都是作业的一部分,是同一个进程组的成员。如果在shell提示符中只输入了一条命令,则可视为一条命令的最小 "流水线",创建一个只有一个成员的作业。
该控制终端的后台进程是与该终端相关联的任何其他工作的成员。终端的后台进程不能读取终端的输入或接收键盘产生的中断,但可以对终端进行写操作。后台的作业可能被停止(暂停),也可能正在运行。如果正在运行的后台作业试图从终端读取,则会自动暂停。
每个终端都是自己的会话,可以有一个前台进程和任意数量的独立后台进程。一个作业正好是一个会话的一部分:属于其控制终端的那个会话。
ps命令在TTY列中显示了进程的控制终端的设备名称。有些进程,如系统守护进程,是由系统启动的,而不是从shell提示符中启动的。这些进程没有控制终端,不是作业的成员,不能被带到前台。对于这些进程,ps命令会在TTY栏中显示一个问号(?)。
后台运行的作业
任何命令或管道都可以在后台启动,只需在命令行末尾加上一个安培拉(&)即可。Bash shell会显示一个作业编号(会话中唯一的)和新的子进程的PID。shell不会等待子进程终止,而是显示shell提示符。
[user@host ~]$ sleep 10000 &
[1] 5947
[user@host ~]$
当包含管道的命令行使用安培号(&)发送到后台时,管道中最后一条命令的PID被用作输出。管道中的所有进程仍然是该作业的成员。
[user@host ~]$ example_command | sort | mail -s "Sort output" &
[1] 5998
您可以使用 jobs 命令显示 Bash 正在跟踪某个会话的作业列表。
[user@host ~]$ jobs
[1]+ Running sleep 10000 &
[user@host ~]$
通过使用带有作业ID(%作业编号)的fg命令,可以将背景作业带到前台。
[user@host ~]$ fg %1
sleep 10000
在前面的例子中,sleep命令现在在控制终端上的前台运行。shell本身再次进入睡眠状态,等待这个子进程退出。
要将前台进程发送至后台,首先在终端中按键盘生成的悬浮请求(Ctrl+Z)。
sleep 10000
^Z
[1]+ Stopped sleep 10000
[user@host ~]$
工作立即被放到后台,并被暂停。
ps j 命令显示与作业相关的信息。PID 是该进程的唯一进程 ID。THe PPID 是该进程的父进程的 PID,即启动(分叉)该进程的进程。PGID是进程组长的PID,通常是作业管道中第一个进程的PID。SID 是会话组长的 PID,通常是控制终端上运行的交互式 shell。由于示例中的sleep命令当前处于暂停状态,所以它的进程状态为T。
[user@host ~]$ ps j
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
2764 2768 2768 2768 pts/0 6377 Ss 1000 0:00 /bin/bash
2768 5947 5947 2768 pts/0 6377 T 1000 0:00 sleep 10000
2768 6377 6377 2768 pts/0 6377 R+ 1000 0:00 ps j
要启动在后台运行的悬浮进程,请使用具有相同作业ID的bg命令。
[user@host ~]$ bg %1
[1]+ sleep 10000 &
shell将警告试图退出带有暂停作业的终端窗口(会话)的用户。如果用户试图立即再次退出,则暂停的作业将被杀死。
结束进程
目标
完成本节内容后,你能够:
- 使用命令来杀死并进程或者与进程通信。
- 确定守护进程的特点。
- 终端用户会话和流程。
信号的过程控制
信号是向进程传递的软件中断。信号向正在执行的程序报告事件。产生信号的事件可以是错误、外部事件(如I/O请求或过期的定时器),也可以是显式请求(使用信号发送命令或键盘序列)。
下表列出了系统管理员在日常流程管理中使用的基本信号。请用其简短的(HUP)或正确的(SIGHUP)名称来表示信号。
基本过程管理信号
型号编号 | 简称 | 定义 | 目的 |
---|---|---|---|
1 | HUP | 挂起 | 用于报告终端的控制进程的终止。也用于请求进程重新初始化(配置重新加载)而不终止。 |
2 | INT | 键盘中断 | 导致程序终止。可以被阻止或处理。通过按INTR组合键(Ctrl+C)发送。 |
3 | QUIT | 键盘退出 | 类似于SIGINT,但也会在终止时产生一个过程转储。通过按QUIT组合键(Ctrl+)发送。 |
9 | KILL | 结束进程,一旦进行无法阻止 | 导致程序突然终止。不能被阻止、忽略或处理;总是致命的。 |
15 默认 |
TERM | 终止 | 导致程序终止。与SIGKILL不同,可以被阻止、忽略或处理。要求程序终止的 "polite "方式;允许自我清理。 |
18 | CONT | 继续 | 发送到一个进程中恢复,如果停止。不能被阻止。即使处理了,也总是恢复进程。 |
19 | STOP | 停止,无法阻止 | 暂停处理。不能被阻止或处理。 |
20 | TSTP | 键盘停止 | 与SIGSTOP不同,可以屏蔽、忽略或处理。通过按SUSP键组合(Ctrl+Z)发送。 |
每个信号都有一个默认的动作,通常是以下之一:
- Term - 导致程序一次性终止(退出)。
- Core - 导致程序保存一个内存映像(核心转储),然后终止。
- Stop 使程序停止执行(暂停)并等待继续(恢复)。
程序可以通过实现处理程序例程来忽略、替换或扩展信号的默认动作,从而对预期的事件信号做出反应。
通过明确请求发送信号的命令
你可以通过按键盘控制序列给它们的当前前台进程发出信号,以暂停(Ctrl+Z)、杀死(Ctrl+C)或核心转储(Ctrl+\)进程。但是,您将使用信号发送命令向后台进程或不同会话中的进程发送信号。
信号可以通过名称(例如-HUP或-SIGHUP)或数字(相关的-1)指定为选项。用户可以杀死自己的进程,但要杀死其他人拥有的进程需要root权限。
kill命令通过PID号向进程发送一个信号。尽管有这个名字,但 kill 命令可以用于发送任何信号,而不仅仅是用于终止程序的信号。你可以使用 kill -l 命令来列出所有可用信号的名称和编号。
[user@host ~]$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP ...output omitted...
[user@host ~]$ ps aux | grep job
5194 0.0 0.1 222448 2980 pts/1 S 16:39 0:00 /bin/bash /home/user/bin/ control job1 5199 0.0 0.1
222448 3132 pts/1 S 16:39 0:00 /bin/bash /home/user/bin/ control job2
5205 0.0 0.1 222448 3124 pts/1 S 16:39 0:00 /bin/bash /home/user/bin/ control job3
5430 0.0 0.0 221860 1096 pts/1 S+ 16:41 0:00 grep --color=auto job
[user@host ~]$ kill 5194
[user@host ~]$ ps aux | grep job
user 5199 0.0 0.1 222448 3132 pts/1 S 16:39 0:00 /bin/bash /home/ user/bin/control job2
user 5205 0.0 0.1 222448 3124 pts/1 S 16:39 0:00 /bin/bash /home/ user/bin/control job3
user 5783 0.0 0.0 221860 964 pts/1 S+ 16:43 0:00 grep --color=auto
job
[1] Terminated control job1
[user@host ~]$ kill -9 5199
[user@host ~]$ ps aux | grep job
user 5205 0.0 0.1 222448 3124 pts/1 S 16:39 0:00 /bin/bash /home/ user/bin/control job3
user 5930 0.0 0.0 221860 1048 pts/1 S+ 16:44 0:00 grep --color=auto
job
[2]- Killed control job2
[user@host ~]$ kill -SIGTERM 5205
user 5986 0.0 0.0 221860 1048 pts/1 S+ 16:45 0:00 grep --color=auto
job
[3]+ Terminated control job3
killall命令可以根据命令的名称,向多个进程发出信号。
使用 pkill 向一个或多个符合选择条件的进程发送信号。选择标准可以是命令名称、特定用户拥有的进程,也可以是全系统的所有进程。pkill 命令包括高级选择标准。
- Command --用模式匹配的命令名称进行处理。
- UID - 一个Linux用户帐户所拥有的进程,有效或真实的。
- GID - 由Linux组帐户所拥有的进程,有效或真实。
- Parent -子过程的具体父过程。
- Terminal -在特定控制终端上运行的过程。
[user@host ~]$ ps aux | grep pkill
user 5992 0.0 0.1 222448 3040 pts/1 S 16:59 0:00 /bin/bash /home/ user/bin/control pkill1
user 5996 0.0 0.1 222448 3048 pts/1 S 16:59 0:00 /bin/bash /home/ user/bin/control pkill2
user 6004 0.0 0.1 222448 3048 pts/1 S 16:59 0:00 /bin/bash /home/ user/bin/control pkill3
[user@host ~]$ pkill control
[1] Terminated control pkill1
[2]- Terminated control pkill2
[user@host ~]$ ps aux | grep pkill
user 6219 0.0 0.0 221860 1052 pts/1 S+ 17:00 0:00 grep --color=auto
pkill
[3]+ Terminated control pkill3
[user@host ~]$ ps aux | grep test
user 6281 0.0 0.1 222448 3012 pts/1 S 17:04 0:00 /bin/bash /home/ user/bin/control test1
user 6285 0.0 0.1 222448 3128 pts/1 S 17:04 0:00 /bin/bash /home/ user/bin/control test2
user 6292 0.0 0.1 222448 3064 pts/1 S 17:04 0:00 /bin/bash /home/ user/bin/control test3
user 6318 0.0 0.0 221860 1080 pts/1 S+ 17:04 0:00 grep --color=auto test [user@host ~]$ pkill -U user
[user@host ~]$ ps aux | grep test
user 6870 0.0 0.0 221860 1048 pts/0 S+ 17:07 0:00 grep --color=auto test [user@host ~]$
登出用户
您可能会因为各种原因而需要将其他用户注销。例如:用户违反了安全规定;用户可能过度使用了资源;用户可能有一个没有反应的系统;或者用户对资料的访问不当。在这些情况下,你可能需要使用信号管理终止他们的会话。
要注销一个用户,首先要确定要终止的登录会话。使用w命令列出用户登录和当前运行的进程。注意TTY和FROM列,以确定要关闭的会话。
所有用户登录会话都与终端设备(TTY)相关联。如果设备名称的形式为pts/N,则是与图形化终端窗口或远程登录会话相关联的伪终端。如果是ttyN形式,则表示用户处于系统控制台、备用控制台或其他直接连接的终端设备上。
[user@host ~]$ w
12:43:06 up 27 min, 5 users, load average: 0.03, 0.17, 0.66
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty2 12:26 14:58 0.04s 0.04s -bash
bob tty3 12:28 14:42 0.02s 0.02s -bash
user pts/1 desk.example.com 12:41 2.00s 0.03s 0.03s w
[user@host ~]$
通过查看会话登录时间,发现用户在系统中的时间。对于每个会话,当前作业(包括后台任务和子进程)消耗的CPU资源在JCPU列中。当前前台进程的CPU消耗在PCPU列中。
进程和会话可以单独或集体发出信号。要终止一个用户的所有进程,请使用pkill命令。由于登录会话中的初始进程(session leader)是为了处理会话终止请求而设计的,并且忽略了不经意的键盘信号,因此,要杀死一个用户的所有进程和登录外壳,需要使用 SIGKILL 信号。
首先使用pgrep确定要杀死的PID号,它的操作和pkill很像,包括使用相同的选项,只是pgrep列出了进程,而不是杀死它们。
[root@host ~]# pgrep -l -u bob
6964 bash
6998 sleep
6999 sleep
7000 sleep
[root@host ~]# pkill -SIGKILL -u bob
[root@host ~]# pgrep -l -u bob
[root@host ~]#
当需要关注的进程在同一个登录会话中,可能没有必要杀死所有用户的进程。使用w命令确定会话的控制终端,然后只杀死引用相同终端ID的进程。除非指定了SIGKILL,否则会话的领导者(这里指的是Bash登录shell)会成功地处理并存活了终止请求,但所有其他会话进程都会被终止。
[root@host ~]# pgrep -l -u bob
7391 bash
7426 sleep
7427 sleep
7428 sleep[root@host ~]# w -h -u bob bob tty3 18:37 5:04 0.03s 0.03s -bash [root@host ~]# pkill -t tty3
[root@host ~]# pgrep -l -u bob
7391 bash
[root@host ~]# pkill -SIGKILL -t tty3
[root@host ~]# pgrep -l -u bob
[root@host ~]#
使用父进程和子进程关系,可以应用同样的选择性进程终止。使用pstree命令查看系统或单个用户的进程树。使用父进程的PID来杀死它们创建的所有子进程。这时,父进程Bash登录shell存活下来,因为信号只针对它的子进程。
[root@host ~]# pstree -p bob
bash(8391)─┬─sleep(8425)
├─sleep(8426)
└─sleep(8427)
[root@host ~]# pkill -P 8391
[root@host ~]# pgrep -l -u bob
bash(8391)
[root@host ~]# pkill -SIGKILL -P 8391
[root@host ~]# pgrep -l -u bob
bash(8391)
[root@host ~]#
监测进程活动
目标
在完成本节内容后,你应该能够描述什么是平均负载,并确定服务器上的高资源使用量的进程。
描述平均负载
负载平均值是Linux内核提供的一种测量方法,它是一种简单的表示系统负载随时间推移而感知到的系统负载的方法。它可以作为一个粗略的衡量标准,用来衡量系统资源请求的待处理数量,并确定系统负载随着时间的推移是增加还是减少。
每隔5秒,内核会根据可运行和不间断状态下的进程数量,收集当前的负载数。这个数字被累积起来,并以最近1分钟、5分钟和15分钟的指数移动平均数来报告。
了解Linux的平均负载计算
负载平均数代表了一个时间段内可感知的系统负载。Linux通过报告有多少进程准备在CPU上运行,有多少进程在等待磁盘或网络I/O完成,来确定这一点。
- 负载数实质上是根据准备好运行的进程数(进程状态R)和等待I/O完成的进程数(进程状态D)。
- 有些UNIX系统只考虑CPU利用率或运行队列长度来表示系统负载。当遇到平均负载高而CPU活动少的情况时,请检查磁盘和网络活动。
负载平均数是一个粗略的测量方法,即当前有多少进程在等待一个请求完成后才能做其他事情。该请求可能是为了CPU时间来运行进程。或者,这个请求可能是为了完成一个关键的磁盘I/O操作,在请求完成之前,即使CPU处于空闲状态,进程也不能在CPU上运行。无论哪种方式,系统负载都会受到影响,系统的运行速度似乎更慢,因为进程在等待运行。
解释显示的平均负载值
uptime命令是显示当前平均负载的一种方法。它可以打印出当前时间、机器开机时间、运行了多少个用户会话,以及当前的平均负载。
[user@host ~]$ uptime
15:29:03 up 14 min, 2 users, load average: 2.92, 4.48, 5.20
负载平均值的三个值代表过去1、5、15分钟内的负载。一眼就能看出系统负荷似乎是在增加还是在减少。
如果平均负载的主要贡献来自于等待CPU的进程,那么可以计算出每个CPU的大致负载值,以确定系统是否有大量的等待。
lscpu命令可以帮助你确定系统有多少个CPU。
在下面的例子中,该系统是一个双核单套接字系统,每个核心有两个超线程。粗略的说,为了调度的目的,Linux会把这个系统当作是四核CPU系统。
[user@host ~]$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
...output omitted...
试想一下,负载数的唯一贡献是来自于需要CPU时间的进程。然后可以将显示的负载平均值除以系统中的逻辑CPU数量。值低于1表示资源利用率令人满意,等待时间最小。高于1的值表示资源饱和,并有一定的处理延迟。
# From lscpu, the system has four logical CPUs, so divide by 4:
# load average: 2.92, 4.48, 5.20
# divide by number of logical CPUs: 4 4 4
# ---- ---- ---# per-CPU load average: 0.73 1.12 1.30
# # This system's load average appears to be decreasing.
# With a load average of 2.92 on four CPUs, all CPUs were in use ~73% of the time.
# During the last 5 minutes, the system was overloaded by ~12%.
# During the last 15 minutes, the system was overloaded by ~30%.
闲置的CPU队列的负载号为0,每个等待CPU的进程在负载号上加1的计数。如果有一个进程在CPU上运行,负载号为1,则该资源(CPU)正在使用中,但没有请求等待。如果该进程运行了整整1分钟,那么它对1分钟的负载平均贡献值为1。
然而,由于磁盘或网络资源繁忙导致的关键I/O不间断休眠的进程也被包含在计数中,并增加了平均负载。虽然不是CPU利用率的指标,但这些进程被添加到队列计数中,因为它们正在等待资源,在获得资源之前无法在CPU上运行。这仍然是由于资源限制导致进程无法运行的系统负载。
在资源饱和之前,负载平均数保持在1以下,因为很少发现任务会在队列中等待。只有当资源饱和导致请求继续排队时,负载平均数才会增加,并被负载计算例程计算。当资源利用率接近100%时,每增加一个请求就开始经历服务等待时间。
一些额外的工具报告负载平均,包括W和top。
实时过程监控
top程序是系统进程的动态视图,显示一个摘要标题,后面是类似于ps信息的进程或线程列表。与静态的ps输出不同,top以可配置的时间间隔持续刷新,并提供了列的重新排序、排序和高亮显示功能。用户的配置可以被保存和持久化。
默认输出列可以从其他资源工具中识别:
- 进程ID(PID)。
- 用户名(USER)是进程的所有者。
- 虚拟内存(VIRT)是进程正在使用的所有内存,包括驻留集、共享库和任何映射或交换的内存页。(在ps命令中标注为VSZ)。
- 驻留内存(RES)是进程使用的物理内存,包括任何驻留共享对象。(在ps命令中标注为RSS)。
- 过程状态(S)显示为:
- D = 不间断睡眠
- R =运行或可运行
- S = 睡眠
- T = 停止或追踪
- Z =僵尸
- CPU时间(TIME)是进程开始后的总处理时间。可以切换到包括所有前一个子系统的累计时间。
顶部的基本项
KEY | 目的 |
---|---|
? or H | 互动按键的帮助。 |
L, T, M | 切换加载、线程和内存头行。 |
1 | 切换显示单个CPU或标题中所有CPU的摘要。 |
S (1) | 改变刷新(屏幕)率,单位是小数点后的秒数(例如,0.5、1、5)。 |
B | 为运行中的进程切换反向高亮显示,默认为粗体。 |
B | 启用在显示中、标题中和运行中的进程中使用黑体。 |
Shift+H | 切换线程;显示过程总结或单个线程。 |
U, Shift+U | 对任何用户名进行过滤(有效、真实)。 |
Shift+M | 按内存使用量排序,按内存使用量从高到低的顺序排列进程列表。 |
Shift+P | 根据处理器的使用情况,按处理器的使用情况依次排序。 |
K (1) | 根据处理器的利用率,依次排列进程列表。当提示时,输入PID,然后发出信号。 |
R (1) | Renice一个过程。当提示时,输入PID,然后输入nice_value。 |
Shift+W | 写入(保存)当前显示配置,以便在下一次顶部重启时使用。 |
Q | 退出 |
Note: | (1) 如果top在安全模式下启动,则不可用。见top(1)。 |
总结
进程是一个可执行程序的运行实例。进程被分配了一个状态,可以是运行、睡眠、停止或僵尸状态。ps命令用于列出进程。
每个终端都是自己的会话,可以有前台进程和独立的后台进程。jobs命令显示一个终端会话中的进程。
信号是一种软件中断,它向正在执行的程序报告事件。kill、pkill和killall命令使用信号来控制进程。
负载平均值是对系统繁忙程度的估计。要显示负载平均值,可以使用 top、uptime 或 w 命令。