一、常用命令总结
1.1 top动态动态展示系统运行状况
top //从整体上看系统负载及整体资源使用情况,按下1可看所有cpu核心的使用
watch -d uptime //显示平均负载情况
top -H -p pid //动态查看一个进程的包含的线程的情况
1.2 ps查看进程信息
ps -ly //列出与本次登录有关的进程信息
ps -aux //BSD语法格式
ps -ef //标准语法格式
ps axjf //进程关系
ps -T -p pid //查看一个特定进程的所有线程,其中输出的SID列代表线程ID
ps -eo lstart,pid,stat,%cpu,%mem,command | grep -E ‘^[DR]’ | sort -nr -k3 //查找指定状态的进程(D/R)
ps -q pid -eo lstart,pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat //打印指定Pid进程的自定义数据
1.2 pstree查看父子进程
pstree -aps pid //查看一个进程的父子进程; -s 显示父进程,-p 显示Pids,会显示线程信息({}内显示)
pstree -apsT pid // -T 不显示线程
1.3 pidstat监测进程状态
pidstat -dut -p 243 // -t 展示与进程相关的线程信息,-u CPU利用率,-d 磁盘IO
pidstat -w -p 243 // 进程上下文切换情况;cswch/s自愿上下文切换,nvcswch/s非自愿上下文切换次数
1.4 kill 销毁进程
kill -9 pid // -9 发送SIGKILL信号强制杀死进程,-15 发送SIGTERM信号给进程
二、进程简述
进程是多任务系统中程序执行的一个实例,从OS内核的角度来看,设计进程的目标是为了有效地实现并管理多任务和资源分配,承担系统资源(CPU时间、内存等)分配实体职责,作为系统资源管理的基本单位,操作系统使用进程实体可以更好地控制、调度和分配计算机资源。进程管理允许操作系统合理地分配CPU时间片、内存、I/O设备等资源,从而优化系统的性能。
Linux系统使用task_struct数据结构(也即进程控制块PCB)来描述了一个进程的所有相关信息,该结构体定义在:include/linux/sched.h文件中,包含有:进程的基本信息,进程id,指向的内存区域的指针,指向文件描述符的指针,所接收的信号,进程状态,调度信息等等。该结构体包含字段很多,主要有以下几个:
volatile long state: 进程状态,如运行、就绪、等待等。
struct thread_info thread_info: 线程信息。
pid_t pid: 进程ID。
/ CPU-specific state of this task: */
struct thread_struct thread: 保存进程切换时下上文信息
struct task_struct *parent: 指向父进程的指针。
struct list_head children: 子进程链表头部。
struct mm_struct *mm: 进程地址空间描述符。
struct files_struct *files: 文件描述符表指针
进程是一种动态的实体,是具有生命周期的,task_struct中的state字段描述了进程当前所处的状态,它由一组标志组成,其中每个标志描述一种可能的进程状态,通过查看进程的状态信息,我们可以了解进程占用的系统资源情况,对系统的运行状态进行分析、调整,从而让系统保持在一个平稳的状态下运行。
存活的进程常见的状态主要有:R、S、D、I、Z,这几种状态的表示意义为:
R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。D状态的进程本身是不消耗CPU资源的,因为不是处于R状态,不会被调度执行。
Z 是 Zombie 的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
其中,值得一提的是不可中断的睡眠状态(D),其实是为了保证进程数据与硬件状态一致,并且正常情况下,不可中断状态在很短时间内就会结束。在内核满足不了进程的请求资源情况下,内核就会让进程暂时变成“D”状态。以应用调用了read系统调用读取文件过程为例,read去读取一个文件,这时候进程会从用户态切换到内核态,内核态read()系统调用在读到真正disk上的文件前,会进行一些文件系统层的操作,这些代码指令的消耗属于”sy”,代表内核态CPU使用;接下来,这个read系统调用会向Linux的Block Layer发出一个 I/O Request,触发一个真正的磁盘读取操作,磁盘控制器从磁盘读取读取数据的过程,是不需要CPU的参与的,这时候会让出CPU的控制权处理其他任务,磁盘控制器取数阶段,进程一般会被置为 TASK_UNINTERRUPTIBLE,Linux 会把这段时间标示成”wa”,代表等待I/O的时间,这里的I/O是指 Disk I/O。磁盘控制器取数完毕后会触发硬件中断,内核中断函数开始处理数据,这个时间属于si状态的CPU使用(si状态的CPU不计入进程的CPU使用时间),软中断处理函数做数据的处理后,返回内核态做进一步处理后read系统调用就返回了,进程返回用户态。
处于D状态的进程,由于进程处于系统调用处理的内核态,所以,kill和停止信号都不能被进程接收。此时的进程在sleep等待内核满足它的资源请求之后,再重新变成Runnable状态。资源请求的过程,一般都是对应的设备控制器来处理的(如磁盘控制器查找数据数据),所以,“不可中断”状态进程并不是占着CPU,也不消耗CPU,而是处于睡眠状态且不响应普通结束进程的信号。内核会通过中断来唤醒进程,例如,当等待的磁盘I/O完成,或者等待的锁被释放,使其从D状态转变为可调度执行的R状态。
2.1 Linux中的几个特殊进程
在Linux系统启动运行的过程中,0、1、2这三个进程起到了至关重要的作用。其中0号进程负责内核级别的初始化和任务,1号进程是用户级别的初始化和进程管理进程,而2号进程是内核线程的管理者,用于执行与内核操作相关的任务。这三个进程共同协作,确保系统正常启动、初始化和运行。
0号进程(内核线程):
作用:0号进程通常表示系统的内核进程,其主要作用是初始化和管理内核线程,以及执行内核级别的任务。这些任务可能包括调度、内存管理、I/O操作和中断处理等。0号进程在初始化 1 号和 2 号进程后,演变为空闲任务。当 CPU 上没有其他任务执行时,就会运行它。
初始化:在引导过程中,0号进程是第一个被内核创建的进程。它负责设置内核数据结构、初始化系统调度器和其他核心组件,以便为其他进程和任务提供运行环境。
不可中断:0号进程是系统中唯一一个不能被终止或杀死的进程,因为它是内核的一部分。
1号进程(init 进程):
作用:1号进程是系统的初始化进程,负责引导系统启动过程、启动其他系统进程和服务,并在系统正常运行期间监控和管理它们。
引导过程:init 进程是系统引导的第一个用户级别进程。它的任务包括执行启动脚本、初始化系统环境和启动系统服务。在一些 Linux 发行版中,init 进程可能被 systemd 或其他进程管理工具替代。
进程管理:init 进程会监控系统中运行的其他进程,以确保它们正常运行,必要时重新启动失败的进程。
2号进程(kthreadd 进程):
作用:2号进程是内核线程管理进程,负责创建、启动和管理内核线程。内核线程是在内核中运行的轻量级进程,通常用于执行与系统操作和硬件交互相关的任务。
内核线程:kthreadd 进程创建内核线程,这些线程用于处理各种内核级别的任务,如磁盘I/O、网络处理、设备驱动程序等。它们是系统中的关键组成部分,确保系统的正常运行。
调度和管理:kthreadd 进程会监控和管理内核线程的运行,确保它们按照需要执行。这些内核线程通常在后台默默地工作,不会与用户级别进程竞争CPU资源。
三、查看进程信息
Linux中查看进程信息的基本命令有ps、top,其中ps(Process Status)查看的是进程信息的一个快照,显示的我们执行ps这个命令时进程的信息,top显示的是进程的动态信息,使用这个命令会看到进程信息的动态变化。
ps、top命令的数据源主要来自Linux的proc和sysfs文件系统。proc文件系统是Linux提供的一种在运行时访问内核内部数据结构、改变内核设置的机制,让用户能够访问和检查内核的内部状态和进程信息,proc文件系统只存在内存当中,挂载在文件系统的/proc挂载点上,以文件系统的方式为访问系统内核数据的操作提供接口。sysfs文件系统的主要目标是展示设备驱动模型中各组件的层次关系,以及提供对内核数据的访问途径,通常被挂载在/sys挂载点上,它们可以由用户空间存取,向用户空间导出内核的数据结构以及它们的属性。
3.1 top 动态查看系统运行状况
top可以从整体上看到系统的负载及CPU、内存等资源的使用情况,其中,top是一个交互式命令,按下1可以可看所有cpu核心的使用情况。也可以通过 top -H -p pid
查看一个进程的包含的线程的资源占用情况。
top展示了两部分的信息:
1.系统状态及资源使用统计信息
包括:系统平均负载(load average),CPU使用率、内存使用、进程数(task)等系统整体的资源使用情况。
2.系统进程信息
系统中进程及状态信息的动态展示。
1.系统统计信息,其中包括:系统负载情况,CPU、内存资源的使用情况
CPU的使用情况,依据处理不同的任务,主要分为:%user、%nice、 %system、%iowait 、%steal等几个方面,分别代表的意思为:
user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。
system(通常缩写为 sys),代表内核态 CPU 时间。
idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。
2.系统中运行的进程信息
top也会按照cpu、内存的使用情况列出进程的信息,也可以通过 top -H -p pid
查看一个进程的包含的线程的资源占用情况。
以 top -H -p 209
为例,结果如下:
其中主要的几个字段意义如下:
VIRT 申请的虚拟内存空间;
RES 实际使用的物理内存;
用户态 CPU 使用率 (%usr);
内核态 CPU 使用率(%system);
运行虚拟机 CPU 使用率(%guest);
等待 CPU 使用率(%wait);
总的 CPU 使用率(%CPU)
3.2 ps查看进程信息
1.ps -ly
列出与 本次登录 有关的进程信息
F 代表这个程序的旗标 (flag), 4 代表使用者为 superuser;
S 代表这个程序的状态 (STAT);常见的进程的 STAT 如上进程描述章节所述;
UID:用户 ID;
NI:这个进程的 nice 值,其表示进程可被执行的优先级的修正数值;
PRI:进程的执行优先权(Priority的简写),其值越小越早被执行;
C:表示 CPU 使用的资源百分比。
2.ps -aux
列出全部进程信息(BSD 格式)
USER :进程的所属用户,
PID :进程的进程ID号,
%CPU :进程占用的 CPU资源 百分比,
%MEM :进程占用的 物理内存 百分比,
VSZ :进程使用掉的虚拟内存量 (Kbytes) ,
RSS :进程占用的固定的内存量 (Kbytes) ,
TTY :与进程相关联的终端(tty),?代表无关,tty1-tty6是本机上面的登入者程序,pts/0表示为由网络连接进主机的程序。
STAT :进程的状态,具体见2.1列出来的部分 ,
START :进程开始创建的时间 ,
TIME :进程使用的总cpu时间,
COMMAND : 进程对应的实际程序。
3.3 pidstat监测进程状态
pidstat
是 sysstat
工具集中的一个命令,一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
pidstat 命令的基本格式为:
1 | pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ] |
其中,常用的选项包括:
-u:显示各个进程的 CPU 使用统计。
-r:显示各个进程的内存使用统计。
-d:显示各个进程的 I/O 使用情况。
-p:指定进程号。
-w:显示每个进程的上下文切换情况。
-t:显示选择任务的线程的统计信息外的额外信息。
-V:显示版本号。
-h:在一行上显示所有活动,方便其他程序解析。
-I:在 SMP 环境下,表示任务的 CPU 使用率/内核数量。
-l:显示命令名和所有参数。
1.pidstat -hdu
在一行显示整体进程的CPU、内存使用情况
其中输出结果主要有:
%usr:进程在用户空间占用 CPU 的百分比;
%system:进程在内核空间占用 CPU 的百分比;
%CPU:任务总的 CPU 使用率;
CPU:正在运行这个任务的处理器编号。
四、进程销毁
进程的生命周期包括了一个进程从创建到销毁的全过程,其中进程状态涉及到就绪态,运行态,停止态,僵尸态,睡眠态等,当进程完成了它的任务后,就会结束。进程的结束可以是正常的,也可以是不正常的。正常的结束包括程序自然结束和接收到 SIGTERM 或 SIGINT 等信号后结束;不正常的结束则可能是由于接收到 SIGKILL 信号,或者是由于程序出现错误而异常终止。
其中,SIGTERM、SIGKILL等信号是发送到进程或同一进程内的特定线程的异步通知,以通知它发生的事件,例如,如果我们可以发送SIGTERM信号或者SIGKILL信号用于终止进程。Linux中可以通过kill向指定的进程发送信号来控制进程的行为,可以通过 kill -l
来获取支持的信号。
kill 默认发送 SIGTERM信号给进程,可以通过-s来指定信号。进程可以捕获SIGTERM信号来实现优雅退出,-9 SIGKILL信号,进程无法捕获,用于强制销毁进程。
kill -9 pid // -9 发送SIGKILL信号强制杀死进程,
kill -15 pid // 发送SIGTERM信号给进程。