目录
进程
Linux通过使用进程来管理多任务。进程就是Linux组织安排正在等待使用CPU的各种程序的方式。
-
ps – 报告当前进程快照
-
top – 显示任务
-
jobs – 列出活跃的任务
-
bg – 把一个任务放到后台执行
-
fg – 把一个任务放到前台执行
-
kill – 给一个进程发送信号
-
killall – 杀死指定名字的进程
-
shutdown – 关机或重启系统
系统启动的时候,内核先把一些它自己的活动初始化为进程,然后运行一个叫做 init 的程序。init, 依次地,再运行一系列的称为 init 脚本的 shell 脚本(位于/etc),它们可以启动所有的系统服务。 其中许多系统服务以守护(daemon)程序的形式实现,守护程序仅在后台运行,没有任何用户接口(User Interface)。因此,即使我们没有登录系统,系统也在忙于执行一些例行事务。
在进程方案中,一个程序可以发动另一个程序被表述为一个父进程可以产生一个子进程。
内核维护每个进程的信息,以此来保持各个进程组织有序。系统会分配给每个进程一个数字,叫做进程(process) ID 或 PID。PID 号按升序分配,init 进程的 PID 总是1。内核也对分配给每个进程的内存和就绪状态进行跟踪以便继续执行这个进程。 像文件一样,进程也有所有者和用户 ID,有效用户 ID,等等。
查看进程
有多个用来查看进程的命令,最常用的是 ps 。默认情况下,ps 不会显示很多进程信息,只是列出与当前终端会话相关的进程。比如我们不加参数的调用该命令:
ldz@MSI:/mnt/c/Users/52840$ ps
PID TTY TIME CMD
2 tty1 00:00:00 bash
85 tty1 00:00:00 ps
进程 2 代表命令bash,进程 85 代表命令ps。其中,字段TTY是“Teletype”的缩写,是指进程的控制终端。TIME字段表示进程执行全过程所消耗的CPU时间长度。(上面两个命令的消耗基本为零)
我们可以加上 x 选项(注意不加短横线),以展示所有终端的进程。
ldz@MSI:/mnt/c/Users/52840$ ps x
PID TTY STAT TIME COMMAND
2 tty1 Ss 0:00 -bash
86 tty2 Ss 0:00 -bash
169 tty2 R 0:00 ps x
有时候在TTY一栏中会出现“?”,表示这个进程没有控制终端。系统中运行的进程较多的时候,可以将ps命令的输出结果使用管道输出到less中,以方便查看。可以看到,上面的结果中出现了一个新的字段 STAT,表示进程当前状态。
状态 | 含义 |
---|---|
R | 运行中。这意味着,进程正在运行或准备运行。 |
S | 正在睡眠。进程没有运行,而是,正在等待一个事件, 比如说,一个按键或者网络分组。 |
D | 不可中断睡眠。进程正在等待 I/O,比方说,一个磁盘驱动器的 I/O。 |
T | 已停止. 已经指示进程停止运行。稍后介绍更多。 |
Z | 死进程或“僵尸”进程。这是一个已经终止的子进程,但是它的父进程还没有清空它。 (父进程没有把子进程从进程表中删除) |
< | 高优先级进程。这可能会授予一个进程更多重要的资源,给它更多的 CPU 时间。 进程的这种属性叫做 niceness。具有高优先级的进程据说是不好的(less nice), 因为它占用了比较多的 CPU 时间,这样就给其它进程留下很少时间。 |
N | 低优先级进程。 一个低优先级进程(一个“nice”进程)只有当其它高优先级进程被服务了之后,才会得到处理器时间。 |
另一个常用的选项组合是 aux (前面不加短横线),它会显示所有用户的进程。并使用BSD风格的输出结果。
ldz@MSI:/mnt/c/Users/52840$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 10432 584 ? Ss 18:36 0:00 /init
ldz 2 0.0 0.0 26328 4116 tty1 Ss 18:36 0:00 -bash
ldz 86 0.0 0.0 26328 4116 tty2 Ss 18:41 0:00 -bash
ldz 170 0.0 0.0 41992 1844 tty1 R 19:42 0:00 ps aux
标题 | 含义 |
---|---|
USER | 用户 ID. 进程的所有者。 |
%CPU | 以百分比表示的 CPU 使用率 |
%MEM | 以百分比表示的内存使用率 |
VSZ | 虚拟内存大小 |
RSS | 进程占用的物理内存的大小,以千字节为单位。 |
START | 进程启动的时间点。过了当天的24时,则用天表示。 |
用 top 命令动态查看进程(相当于任务管理器)
ps 命令只提供其执行时刻的系统状态快照。为了查看动态的信息,可以使用top命令。top 命令以进程活动顺序显示连续更新的系统进程列表(默认三秒更新一次)。top 显示结果由两部分组成: 上面是系统概要,下面是进程列表,以 CPU 的使用率排序。
top - 19:57:40 up 1:21, 0 users, load average: 0.52, 0.58, 0.59
Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.1 hi, 0.0 si, 0.0 st
KiB Mem : 16619820 total, 9563308 free, 6820036 used, 236476 buff/cache
KiB Swap: 36708220 total, 36699112 free, 9108 used. 9658928 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 10432 584 548 S 0.0 0.0 0:00.02 init
2 ldz 20 0 26328 4116 4024 S 0.0 0.0 0:00.15 bash
86 ldz 20 0 26328 4116 3904 S 0.0 0.0 0:00.14 bash
172 ldz 20 0 42228 1928 1404 R 0.0 0.0 0:00.00 top
其中系统概要包含许多有用信息。
行号 | 字段 | 意义 |
---|---|---|
1 | top | 程序名。 |
19:57:40 | 当前时间。 | |
up 1:21 | 这是正常运行时间。它是计算机从上次启动到现在所运行的时间。 在这个例子里,系统已经运行了六个半小时。 | |
0 users | 有两个用户登录系统。 | |
load average: | 加载平均值是指,等待运行的进程数目,也就是说,处于可以运行状态并共享 CPU 的进程个数。 这里展示了三个数值,每个数值对应不同的时间段。第一个是最后60秒的平均值, 下一个是前5分钟的平均值,最后一个是前15分钟的平均值。若平均值低于1.0,则指示计算机 工作不忙碌。 | |
2 | Tasks: | 总结了进程数目和这些进程的各种状态。 |
3 | Cpu(s): | 这一行描述了 CPU 正在进行的活动的特性。 |
0.3%us | 0.3% 的 CPU 被用于用户进程。这意味着进程在内核之外。 | |
0.3%sy | 0.3%的 CPU 时间被用于系统(内核)进程。 | |
0.0%ni | 0.0%的 CPU 时间被用于"nice"(低优先级)进程。 | |
99.3%id | 99.3%的 CPU 时间是空闲的。 | |
0.0%wa | 0.0%的 CPU 时间来等待 I/O。 | |
4 | Mem: | 展示物理内存的使用情况。 |
5 | Swap: | 展示交换分区(虚拟内存)的使用情况。 |
top 程序运行过程中接受一系列从键盘输入的命令。其中h 命令用来显示程序的帮助信息,q 命令退出top程序。
中断进程
在终端中,通常情况下(不是全部)可以通过输入 Ctrl-c,中断一个程序。
把进程放置到后台执行
我们可以在不终止程序的情况下让shell提示符返回。即可以在终端中执行其他命令或程序。为了启动一个程序并让它立即在后台 运行,我们在程序命令之后,加上”&”字符:
ldz@MSI:/mnt/c/Users/52840$ gedit &
[1] 580
ldz@MSI:/mnt/c/Users/52840$
执行命令之后,gedit编辑器窗口出现,并且立即返回shell提示符。同时打印一条任务控制信息,这条信息告诉我们,已经启动了任务号为 1 ,PID 为580的程序。
我们可以利用 jobs 命令,列出从本终端中启动的任务。
ldz@MSI:/mnt/c/Users/52840$ jobs
[1]+ Running gedit &
结果显示本终端中有一个任务,编号为 1,正在运行,启动该任务的命令为 gedit & 。
进程返回到前台执行
一个在后台运行的进程对一切来自键盘的输入都免疫,也不能用 Ctrl-c 来中断它。我们可以使用 fg 命令让一个进程返回前台,格式为fg %任务号:
ldz@MSI:/mnt/c/Users/52840$ jobs
[1]+ Running gedit &
ldz@MSI:/mnt/c/Users/52840$ fg %1
gedit
如果只有一个后台任务,可以不指定任务号。
(暂时)停止进程
可以在终端中输入 Ctrl-z 来暂停一个进程,而不是关闭它。
ldz@MSI:/mnt/c/Users/52840$ gedit
^Z
[1]+ Stopped gedit
ldz@MSI:/mnt/c/Users/52840$
停止程序之后,我们无法对gedit 窗口做任何操作。可以使用 fg 命令恢复程序到前台,或者使用 bg 命令将暂停的程序转移到后台(用法同 fg)。
从命令行启动图形界面程序有两个好处,第一个是你想要启动的程序可能没有在窗口管理器菜单中列出来(比如xlogo,一个显示X图标的窗口程序),第二个是从命令行启动一个程序, 能够看到一些错误信息,如果从图形界面中运行程序的话,这些信息是不可见的。
有时候, 一个程序不能从图形界面菜单中启动。通过从命令行中启动它,我们可能会看到能揭示问题的错误信息。一些图形界面程序还有许多有意思并且有用的命令行选项。
信号
信号是操作系统与程序之间进行通信时所采用的几种方式中的一种。 我们可以使用组合键和命令向运行的程序发送一个信号,程序,相应地,监听信号的到来,当程序接收到信号之后,则做出响应。
kill命令用来“杀死”程序(任何终端的)。格式为:kill PID 或者 kill %任务号
ldz@MSI:/mnt/c/Users/52840$ xlogo &
[1] 715
ldz@MSI:/mnt/c/Users/52840$ kill 715
[1]+ Terminated xlogo
kill 命令不是真的“杀死”程序,而是给程序发送信号。 在使用 Ctrl-c 和 Ctrl-z 的过程中我们已经看到信号的实际用法。当终端接受了其中一个按键组合后,它会给在前端运行的程序发送一个信号。在使用 Ctrl-c 的情况下,会发送一个叫做 INT(Interrupt,中断)的信号;当使用 Ctrl-z 时,则发送一个叫做 TSTP(Terminal Stop,终端停止)的信号。
通过kill命令给进程发送信号
常用语法形式:kill -signal PID...
注意,信号既可以是编号,也可以用名字来指定,还可以在名字前面加上字母“SIG”
如果在命令行中没有指定信号,那么默认情况下,发送 TERM(Terminate,终止)信号。
编号 | 名字 | 含义 |
---|---|---|
1 | HUP | 挂起(Hangup)。这是美好往昔的残留部分,那时候终端机通过电话线和调制解调器连接到 远端的计算机。这个信号被用来告诉程序,控制的终端机已经“挂断”。 通过关闭一个终端会话,可以展示这个信号的作用。在当前终端运行的前台程序将会收到这个信号并终止。 许多守护进程也使用这个信号,来重新初始化。这意味着,当一个守护进程收到这个信号后, 这个进程会重新启动,并且重新读取它的配置文件。Apache 网络服务器守护进程就是一个例子。 |
2 | INT | 中断。实现和 Ctrl-c 一样的功能,由终端发送。通常,它会终止一个程序。 |
9 | KILL | 杀死。这个信号很特别。尽管程序可能会选择不同的方式来处理发送给它的 信号,其中也包含忽略信号,但是 KILL 信号从不被发送到目标程序。而是内核立即终止 这个进程。当一个进程以这种方式终止的时候,它没有机会去做些“清理”工作,或者是保存工作。 因为这个原因,把 KILL 信号看作最后一招,当其它终止信号失败后,再使用它。 |
15 | TERM | 终止。这是 kill 命令发送的默认信号。如果程序仍然“活着”,可以接受信号,那么这个它会终止。 |
18 | CONT | 继续。在一个停止信号后,这个信号会恢复进程的运行。 |
19 | STOP | 停止。这个信号导致进程停止运行,而不是终止。像 KILL 信号,它不被发送到目标进程,因此它不能被忽略。 |
eg: 通过 kill 命令发送一个 HUP信号,接收信号的程序会挂起,并在终端中打印一条信息,表示这个进程已经接收了挂起信号。但是这条信息可能不会立即显示,需要多按几次enter键才会显示出来。
ldz@MSI:/mnt/c/Users/52840$ gedit &
[1] 754
ldz@MSI:/mnt/c/Users/52840$ kill -1 754
ldz@MSI:/mnt/c/Users/52840$
[1]+ Hangup gedit
ldz@MSI:/mnt/c/Users/52840$
进程,和文件一样,拥有所有者,所以为了能够通过 kill 命令来给进程发送信号, 你必须是进程的所有者(或者是超级用户)。
编号 | 名字 | 含义 |
---|---|---|
3 | QUIT | 退出 |
11 | SEGV | 段错误(Segmentation Violation)。如果一个程序非法使用内存,就会发送这个信号。也就是说, 程序试图写入内存,而这个内存空间是不允许此程序写入的。 |
20 | TSTP | 终端停止(Terminal Stop)。当按下 Ctrl-z 组合键后,终端发送这个信号。不像 STOP 信号, TSTP 信号由目标进程接收,且可能被忽略。 |
28 | WINCH | 改变窗口大小(Window Change)。当改变窗口大小时,系统会发送这个信号。 一些程序,像 top 和 less 程序会响应这个信号,按照新窗口的尺寸,刷新显示的内容。 |
通过 killall 命令给多个进程发送信号
通过 killall 命令,给匹配特定程序或用户名的多个进程发送信号。语法形式为:killall -u username -signal processname...
如果不指定用户名,则默认当前用户。注意,和 kill 命令一样,你必须拥有超级用户权限才能给不属于你的进程发送信号。
eg:
ldz@MSI:/mnt/c/Users/52840$ gedit &
[1] 773
ldz@MSI:/mnt/c/Users/52840$ gedit &
[2] 780
ldz@MSI:/mnt/c/Users/52840$ killall gedit
[1]- Terminated gedit
[2]+ Done gedit
更多和进程相关的命令
监测进程是一个很重要的系统管理任务,所以有许多命令与它相关,如下表。
命令名 | 命令描述 |
---|---|
pstree | 输出一个树型结构的进程列表(processtree),这个列表展示了进程间父/子关系。 |
vmstat | 输出一个系统资源使用快照,包括内存,交换分区和磁盘 I/O。 为了看到连续的显示结果,则在命令名后加上更新操作延时的时间(以秒为单位)。例如,“vmstat 5”。 ,按下 Ctrl-c 组合键, 终止输出。 |
xload | 一个图形界面程序,可以画出系统负载随时间变化的图形。 |
tload | terminal load与 xload 程序相似,但是在终端中画出图形。使用 Ctrl-c,来终止输出。 |
利用shutdown命令关机或重启
shutdown命令可以安全地关闭或重启Linux系统,它在系统关闭之前给系统上的所有登录用户提示一条警告信息。shutdown通过通知init进程,要求它改换运行级别来实现。运行级别0用来关闭系统,运行级别6用来重启系统,运行级别1用来使系统进入执行系统管理任务状态,如果没有给出 -h 或 -r 选项时,这是 shutdown 默认运行级别为 1。
语法格式为:shutdown -option time (自定义警告信息)
选项 | 长选项 | 选项描述 |
---|---|---|
-h | 关机后关闭电源 | |
-r | --reboot | 重启 |
-c | 取消运行中的shutdown进程。不能为此选项指定time参数,但是可以在命令行中输入一条取消原因向所有用户说明。(一般的shutdown指令可以用按“+”号来进行中断) | |
-k | 不会真正关机,只是发送警告信息 | |
-f | 重启时跳过磁盘检测(即快速重启) | |
-F | 重启时强制磁盘检测 | |
-n | 不通过 init ,快速关机。不建议用这个选项 | |
-t | 在改变到其他运行级别之前,告诉init多久后关机 |
其中,time参数是强制的,可以设置为精确的时间点关机比如:20:59,或者设置为一段时间后关机比如:+10(表示10分钟后关机),如果想要立刻关机则可以设置为:now。
自定义的警告消息一般在延迟关机的时候设置,比如10分钟后关机,可以写一条警告消息通知所有登录的用户:'the system will shutdown in 10 minutes'。
eg:
ldz@MSI:/mnt/c/Users/52840$ shundown +10 '我要在十分钟后关机咯'
shutdown scheduled for 五 2018-10-26 13:29:38 CST,use 'shutdown -c' to cancel.