linux进程管理

admin 2022年04月22日 776次浏览

放在硬盘上的程序,通过用户的执行来触发,触发后会加载到内存中成为一个个体,这就是进程。 为了让操作系统可管理这个进程,因此进程就会给执行者权限、属性等参数,及程序所需要的脚本与数据或文件数据等, 最后再给予一个 PID ,系统就是通过这个 PID 来判断该 进程是否具有执行权限

1、进程简介

1.1、子进程与父进程

我们打开一个bash后,这个bash就会产生一个PID,当我们在这个bash中再执行其他命令,如 vi 命令时,系统又会给 vi 分配一个PID,这时我们查看进程时,就会发现一个有趣的现象,如下图:

在上图中,我们可以发现bash进程的PID是8,vim的PID是34,ps的PID是46,但是vim和ps的PPID都是8,那么就说明vim和ps都是bash的子进程(PID为进程号,PPID为父进程号)

1.2、进程调用流程

进程都会由父进程以复制的方式产生一个一模一样的子进程,然后被复制出来的子进程再以 exec 的方式来执行实际要进行的程序,最终就成为一个子进程的存在

  • 系统先以 fork 的方式复制一个与父进程相同的临时进程,这个进程与父进程唯一的差别就是 PID 不同,但是这个临时进程还会多一个 PPID 的参数,这个 PPID 就是父进程的进程标识

  • 临时进程开始以 exec 的方式加载实际要执行的程序,如上图,新的程序名称为 vim ,最终子进程的进程代码就会变成 vim 了

1.3、常驻进程

一般而言,我们的一个命令执行完毕后,内存就会释放,但是有些任务(例如定时任务)需要周期性自动运行,因此就需要常驻到内存中,便于周期性的重复执行

常驻在内存当中的进程通常都是负责一些系统所提供的功能以服务用户各项任务,因此这些常驻程序就会被我们称为:服务 (daemon)。这些程序被执行后,他会启动一个可以负责网络监听的端口 ,以提供外部客户端的连接请求

2、任务管理

2.1、任务管理的限制

  • 这些任务所触发的进程必须来自于自己 shell 的子进程(只能管理自己的 bash)

  • 前台任务:可以控制与执行命令的这个环境称为前台任务 (foreground)

  • 后台任务:可以自动执行的任务,无法使用 [ctrl]+c 终止,可使用 bg、fg 调用该任务

  • 后台执行的任务不能等待 terminal 或 shell 的输入(input)

2.2、任务管理

  • 直接将任务丢到后台中执行:&

    我们在只有一个 bash 的环境下,如果想要同时执行多个任务, 那么我们可以将某些任务直接丢到后台去运行,让我们可以继续操作前台任务最简单的方法就是利用 & 这个符号即可。例如我们在使用 vim 编辑文件时,又需要做其他的操作,我们可以这样操作

    oldyan@oldyan-pc:~$ vim file &
    [1] 60
    oldyan@oldyan-pc:~$
    
    # [1]:任务号码
    # 60:进程的PID
    
  • 查看后台运行的任务:jobs

    我们可以使用 jobs [-lrs] 命令来查看后台所有的任务,其中 + 代表最近被放到后台的任务, - 代表最近最后第二个被放置到后台的任务,而超过第三个以后的任务,就不会有 + - 符号存在了

    -l:除了列出任务号码与命令外,还可以同时列出 PID

    -r:只显示后台正在运行的任务

    -s:只显示后台暂停的任务

    oldyan@oldyan-pc:~$ jobs
    [1]   Stopped                 vim file
    [2]-  Stopped                 vim 1.txt
    [3]+  Stopped                 vim 2.txt
    oldyan@oldyan-pc:~$ 
    
  • 将后台任务移到前台执行:fg

    将后台任务调到前台来执行,首先使用 jobs 查看任务号码(就是中括号中的那个号码),然后使用 fg 任务号码 就可以将后台任务调到前台来执行了(例如:fg 1)

  • 使后台暂停的任务进入运行状态:bg

    使用 bg [任务号] 可以使后台处于暂停状态的任务,在后台继续运行

  • 管理后台任务进程:kill

    对于后台任务,可以使用 fg 将其调到前台来运行,也可以使用 kill [signal] PID | %任务号 将其直接删除

    signal :代表对后面的 PID或任务号 执行的指令

    -1 :重新读取一次参数的配置文件 (类似 reload)

    -2 :代表与由键盘输入 [ctrl]-c 同样的动作

    -9 :立刻强制删除一个任务

    -15:以正常的进程方式终止一项任务

    需要注意的是,-9 通常是用在强制删除一个不正常的任务或进程时所使用的, -15 则是以正常步骤结束一项任务或进程(15 也是默认值)。例如,在使用 vim 的时候,会产生一个 .filename.swp 文件, 如果使用 -15 时,vim 会尝试以正常的步骤来结束掉该 vim 进程, 所以 .filename.swp 会主动的被移除;但如果是使用 -9,由于该 vim 进程会被强制移除掉,因此, .filename.swp 就会继续存在文件系统当中

    另外, kill 后面接的数字默认会是 PID ,如果想要管理 bash 的任务控制,就得要加上 %任务号

3、进程管理

3.1、查看进程

3.1.1、查看某个时间点的进程情况:PS

通过 PS 命令,可以查看某个时间点的进程运行情况

# 查看系统所有进程
root@oldyan-pc:/home/oldyan# ps aux

# 查看系统所有进程
root@oldyan-pc:/home/oldyan# ps -lA

# 同时显示进程树
root@oldyan-pc:/home/oldyan# ps axjf

选项与参数:

-A :所有的进程均显示出来

-a :不显示与终端相关的所有进程

-u :有效使用者相关的进程

x :通常与 a 一起使用,可列出较完整信息

输出格式:

l :较长、较详细的将该 PID 的信息列出

j :任务的格式

-f :更详细的输出

3.1.1.1、仅查看自己的进程
root@oldyan-pc:/home/oldyan# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S     0     7     1  0  80   0 -  2235 -      tty1     00:00:00 init
0 S     0   258     8  0  80   0 -  4131 -      tty1     00:00:00 su
0 S     0   259   258  0  80   0 -  3928 -      tty1     00:00:00 bash
0 R     0   273   259  0  80   0 -  4274 -      tty1     00:00:00 ps

列名解释:

  • F:进程标识,说明这个进程的权限,常见号码有:
  • 若为 4 表示此进程的权限为 root

  • 若为 1 则表示此子进程仅进行复制而没有实际执行

  • S:进程的状态,主要的状态有:
  • R :该程序正在运作中

  • S :该进程目前正在睡眠状态,但可以被唤醒

  • D :不可被唤醒的睡眠状态,通常这个进程可能在等待 I/O 的情况

  • T :停止状态,可能是在任务控制(后台暂停)或跟踪状态

  • Z :僵尸状态,进程已经终止但却无法被移除至内存外

  • UID、PID、PPID:此进程被该 UID 所拥有、进程的 PID 号码、此进程的父进程 PID 号码

  • C:代表 CPU 使用率,单位为百分比

  • PRI/NI:此进程被 CPU 所执行的优先级,数值越小代表该进程越快被 CPU 执行

  • ADDR/SZ/WCHAN:与内存有关,ADDR 说明该进程在内存的哪个部分,如果是个运行中的进程,一般就会显示 - ;/SZ 说明此进程用掉多少内存;WCHAN 说明目前进程是否运作中,同样的, 若为 - 表示正在运作中

  • TTY:登陆者的终端位置,若为远程登录则使用动态终端接口名称

  • TIME:使用 CPU 的时间(是此进程实际花费 CPU 运行的时间,而不是系统时间)

  • CMD:就是触发该进程的命令

僵尸进程:一般造成僵尸进程的成因是,因为该进程应该已经执行完毕,或者是因故应该要终止了, 但是该进程的父进程却无法完整的将该进程结束掉,而造成那个进程一直存在内存当中。 如果发现在某个进程的 CMD 后面还接上 <defunct> 时,就代表该进程是僵尸进程

通常,当系统不稳定的时候就容易造成所谓的僵尸进程,可能是因为程序写的不好,或者是使用者的操作习惯不良等等所造成。如果发现系统中很多僵尸进程时,就需要找出该进程的父进程,对主机的环境进行优化

3.1.1.2、查看系统所有进程
root@oldyan-pc:/home/oldyan# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   8956   604 ?        Ssl  09:43   0:00 /init
root         7  0.0  0.0   8940   572 tty1     Ss   09:43   0:00 /init
oldyan       8  0.0  0.0  16916  3604 tty1     S    09:43   0:00 -bash
root       258  0.0  0.0  16524  2084 tty1     S    21:57   0:00 su
root       259  0.0  0.0  15712  2236 tty1     S    21:57   0:00 bash
root       275  0.0  0.0  17392  1888 tty1     R    22:23   0:00 ps aux
  • USER:该进程属于那个使用者账号的

  • PID:该进程的进程 ID

  • %CPU:该进程使用掉的 CPU 资源百分比

  • %MEM:该进程所占用的物理内存百分比

  • VSZ:该进程使用掉的虚拟内存量 (Kbytes)

  • RSS:该进程占用的固定的内存量 (Kbytes)

  • TTY:该进程是在那个终端上面运行,如果与终端无关则显示 ?,tty1-tty6 则为本机登陆, 如果是 pts/0 等等的,则表示为由网络连接进主机的进程

  • STAT:该进程目前的状态,状态显示与 ps -l 的 S 标识相同 (R/S/T/Z)

  • START:该进程被触发启动的时间

  • TIME:该进程实际使用 CPU 运行的时间

  • COMMAND:该进程的实际命令

3.1.2、动态观察进程状态:top

相对于 ps 是选取一个时间点的进程状态, top 则可以持续的检测进程运行的状态

3.1.2.1、语法

top [-d 数字] | top [-bnp]

选项与参数:

​ -d :后面可以接秒数,就是整个进程界面更新的秒数。默认是 5 秒

​ -b :以批量的方式执行 top ,通常会配合数据流重定向来将批量的结果输出成为文件

​ -n :与 -b 搭配,需要进行几次 top 的输出结果

​ -p :指定监控某些个 PID

在 top 执行过程当中可以使用的按键命令:

​ ? :显示在 top 当中可以输入的按键命令

​ P :以 CPU 的使用排序显示

​ M :以内存的使用排序显示

​ N :以 PID 来排序

​ T :由该进程使用的 CPU 时间累积 (TIME+) 排序

​ k :给予某个 PID 一个信号 (signal)

​ r :给予某个 PID 重新制订一个 nice 值

​ q :退出 top

3.1.2.2、指标解释
[root@localhost ~]# top
top - 21:25:43 up 18 min,  1 user,  load average: 0.00, 0.01, 0.05
Tasks:  96 total,   2 running,  94 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   995640 total,   714464 free,   168816 used,   112360 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.   695376 avail Mem 
----- 空白行 -----
   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND           
  1056 root      20   0  158988   5616   4264 S  1.0  0.6   0:00.77 sshd               
   736 root      20   0  552788  11072   7044 S  0.3  1.1   0:00.31 NetworkManager     
  1043 root      20   0  214432   3796   3088 S  0.3  0.4   0:00.32 rsyslogd           
  1334 root      20   0  161968   2172   1552 R  0.3  0.2   0:00.07 top               
     1 root      20   0  128028   6648   4164 S  0.0  0.7   0:02.28 systemd           
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd           
     4 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H       
     5 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kworker/u256:0     
     6 root      20   0       0      0      0 S  0.0  0.0   0:00.13 ksoftirqd/0       
  • 各行信息解释

    • 第一行:(top

      21:25:43:当前时间

      up 18 min:从开机到现在一共经过了多长时间

      1 user:在线用户数量

      load average:系统在 1、 5,、15 分钟的平均工作负载,代表的是 1、5、15 分钟,系统平均要负责运行多少个进程,数值越小代,表系统越闲

    • 第二行:(Tasks)显示的是目前进程的总量与个别进程在什么状态(running、sleeping、stopped、zombie),需要注意的是最后的 zombie ,如果不是 0,那么需要看看到底是那个进程变成了僵尸进程

    • 第三行(%Cpu(s))显示的是 CPU 的整体负载,每个项目可使用 ? 查看。需要特别注意的是 wa 项目,该项目代表的是 I/O wait, 通常系统会变慢都是 I/O 产生的问题比较大,因此这里需要注意这个项目耗用 CPU 的资源,另外,如果是多内核的设备,可以按下数字键【1】来切换成不同 CPU 的负载率

    • 第四行和第五行,表示目前的物理内存与虚拟内存 (Mem/Swap) 的使用情况,要注意的是 swap 的使用量要尽量的少,如果 swap 被用的很大量,表示系统的物理内存不足

    • 第六行(空白行)这是当在 top 程序当中输入命令时,显示状态的地方

  • 进程列值

    • PID :进程ID

    • USER:该进程所属用户

    • PR :进程的优先执行顺序,越小越早被执行

    • NI :与 PR 有关,也是越小越早被执行

    • %CPU:CPU 的使用率

    • %MEM:内存的使用率

    • TIME+:CPU 使用时间的累加

4、 /proc/目录下各文件简介

我们之前提到的所谓的进程都是在内存中的,而内存当中的数据又都是写入到 /proc/* 这个目录下的,所以,我们也可以直接查看 /proc 这个目录当中的文件

文件名 文件内容
/proc/cmdline 加载内核时所执行的相关命令和参数
/proc/cpuinfo CPU 的相关信息
/proc/devices 该文件记录了系统各个主要设备的主要设备代号,与 mknod 有关
/proc/filesystems 目前系统已经加载的文件系统
/proc/interrupts 目前系统上面的 IRQ 分配状态
/proc/ioports 目前系统上面各个设备所配置的 I/O 地址
/proc/kcore 内存的大小,文件过大,不建议查看
/proc/loadavg 系统负载的三个平均数值
/proc/meminfo 使用 free 列出的内存信息
/proc/modules 目前系统已经加载的模块(驱动)列表
/proc/mounts 系统已经挂载的数据,就是使用 mount 调出来的数据
/proc/swaps 交换分区数据
/proc/partitions 使用 fdisk -l 对应的所有分区信息
/proc/uptime uptime信息
/proc/version 内核的版本,就是用 uname -a 显示的信息
/proc/bus/* 总线设备、USB设备信息