Linux 进程管理

进程的概念

要理解进程是什么,我们首先要知道什么是程序,程序就是基于某种编程语言,编写的一系列代码文件;

如果要运行一个程序,首先需要使用某种编程语言定义的规则编写代码文件,将代码文件存放再硬盘的一个指定位置上,使用编译器或者解释器执行这个代码文件的时候,解释器会进行系统调用,此时操作系统控制硬件将指定的程序文件从硬盘加载到内存中,这就是程序的启动过程。

程序加载到内存后,CPU就能从内存中获取程序代码,从而根据程序代码中的相关指令来做某些操作;

所以这就是运行程序的一个过程,这个过程很复杂,所以为了方便交流,就给一个程序的运行过程取了个名字,叫做进程。

所以,由此可知,进程就是一个程序的运行过程,是操作系统控制计算机硬件运行应用程序的过程


线程的概念

进程是对程序的运行过程的一个名词简称,而线程是进程内部的一个执行单位,简单理解就是线程是进程中的一个独立执行流,用于实现某个功能或者指令。

多线程:多线程就是进程里面的两个或多个执行流一起处理任务,这样可以更高效地使用CPU和其他资源。在一个进程中,所有的线程共享该进程的地址空间。这意味着它们共享内存、全局变量、代码段和其他系统资源。

Linux中的进程

在Linux中,每个进程都会分配一个ID号(PID)来进行唯一标识,通过PID可以实现对进程的管理。


查看进程信息

在Linux中,有很多工具可以用来查看进程的信息,可以看到CPU、内存等的占用等。常用的工具有top、htop、ps、pstree等。


pstree 查看进程树

这个工具主要是拿来看进程的父子关系的,一般的Linux发行版系统没有装这个工具,需要自己手动安装才行。

如果只想看进程信息,不想查看线程,使用 -T(大写)参数 就可以了

pstree -T

如果还想显示进程的PID,通过加 -p 参数 就可

pstree -p

ps 查看所有进程快照信息

ps也是拿来查看进程信息的,但是ps默认只会看到与当前shell会话相关的进程。而且显示的是执行这个命令瞬间的进程信息状态。

例如:这里查看的是当前终端的进程,有两个,一个是执行的ps进程,还有一个就是当前终端的bash进程

常用的三个参数:

  • a:查看所有终端的进程信息

  • u:显示每个进程是以谁的身份运行等信息

  • x:显示和终端无关的进程,例如守护进程等

例如:

输出信息说明:

  • USER:每个进程都有一个与其关联的用户ID(UID),这个UID决定了进程的执行权限和对资源的访问权限,这里的USER指的是启动该进程的用户

  • PID:进程ID号。这是每个进程的唯一标识符。

  • %CPU:该进程当前占用的CPU使用率。

  • %MEM:该进程当前占用的物理内存使用率。

  • VSZ:该进程使用的虚拟内存量,单位是KB。

  • RSS:该进程占用的实际物理内存(或者说,常驻内存)的大小,单位是KB。 这不包括交换出去的部分。

  • TTY:与该进程关联的终端类型。对于后台进程,?表示没有和任何终端关联。

  • STAT:进程的状态。它是一个字符码,表示进程的状态(例如,R代表运行中,S代表休眠,Z代表僵尸进程等)。

  • COMMAND:用于启动该进程的原始命令及其参数。

进程所有者说明:

例如,如果一个用户名为alice的用户启动了一个程序,那么这个进程的所有者就是alice。这意味着这个进程在系统上的操作权限将受到alice用户权限的限制。

查看指定的属性信息:

如果不想查看进程的那么多属性信息,可以使用 -o 参数 来指定需要输出的属性。常见的有:pid cmd %cpu %mem,使用逗号来进行分隔。

例如:查看Linux主机上的所有进程

ps -eo user,pid,%cpu,cmd 或 ps -Ao user,pid,%cpu,cmd 或 ps -axo user,pid,%cpu,cmd

ps命令的选项支持三种风格

1. UNIX选项 如: -A -e  # 单个字母

2. GNU选项 如: --help  # 完整单词

3. BSD选项 如: a       # 只需要一个字母

ps除了常用的aux三个参数还,还有一些参数也很常用:

  • -A:列出系统上的所有进程,等同于 -e 选项,相当于 ax的结合
ps -A 或 ps -e 表示列出所有进程。

#  -a:是与终端有关的所有进程, x选项是显示和终端无关的进程

ps ax 也是列出所有进程。

ps -ef 和 ps aux输出区别:

ps -ef:

  • -e: 显示所有进程。效果等同于-A或者 ax

  • -f: 使用“完整格式”输出。这通常包括UID、PID、PPID、TTY、CMD等

  • 一般要查看进程的PID、PPID等信息,用ps -ef即可

ps -aux:

  • a: 显示所有进程,包括其他用户的进程。

  • u: 显示用户/所有者相关的详细信息。会输出:USER、PID、%MEM、%CPU、RSS(实际内存大小)、CMD等内容

  • x: 显示与终端无关的进程。

  • 如果是要看内存、CPU的占用,用ps -aux 命令即可。


prtstat 查看单个进程的详细信息

使用prtstat命令时,需要指定进程的PID来进行查看。


pgrep 查找符合特定名称或其他属性的进程的PID

还有一个叫作pidof的工具,效果和pgrep差不多。但是pgrep的灵活性和功能比pidof更好。

例如:查看mysqld进程的PID

使用pgrep的 -a 参数,不但可以显示进程的PID,还会显示进程的完整命令

pgrep -a process_name

如果还想显示某进程的子进程信息,加 -P(大写)即可,但是这个时候不能用进程的名字了,要用进程的PID

例如:

pgrep -aP 960604

top工具:动态实时查看进程信息

top可以动态查看进程的信息变化。

  • VIRT:Virtual Memory Size: 进程使用的总虚拟内存,包括 RAM 和 Swap,单位是KiB

  • RES:Resident Memory Size: 进程在实际 RAM 中使用的内存大小,单位是KiB。

  • SHR:Shared Memory: 进程使用的共享内存大小,单位是KiB

  • %MEM - Memory Usage (RAM): 进程使用的 RAM 百分比。

  • COMMAND - Command: 启动进程的命令或程序名称。

top也提供了很多快捷键盘,以下是一些常用的快捷键:

按下 M 会根据内存使用率对进程排序。

按下 P(大写) 会根据 CPU 使用率对进程排序。

按下 c 会显示完整的命令行,或仅显示命令名。

按下 m 可以显示或者隐藏内存状态行

隐藏状态:

显示状态:

按下 e 可以使得内存显示单位切换,默认是kb

M为单位:

G为单位:

u 键,可以显示指定用户的进程


htop top的增强版

htop是top工具的增强版,功能更多,显示更好看。

显示信息说明:

  • RES:表示进程当前使用的物理内存的大小

  • S:进程当前的状态

  • CPU%:进程使用的 CPU 百分比

  • MEM%:进程使用的内存百分比

htop的快捷键:

F4:可以根据进行的名称进行筛选

F6:可以按照某个属性(例如CPU、内存等)进行排序

F5:树形显示模式查看进程的父子关系

htop的RES、ps的RSS区别:

  • htop是基于top开发而来的,所以htop的RES(Resident Memory Size)和top的RES是同一个意思,表示进程当前使用的物理内存的大小。代表了进程在 RAM 中实际占用的内存部分,不包括交换出去的部分或者还没有被加载到 RAM 的部分。

  • ps显示的RSS(Resident Set Size)和htop显示的RES类似,也表示进程使用的物理内存的大小。它同样不包括交换空间中的内存。


lsof 查看进程打开的文件

lsof是list open files的缩写,用于列出系统中所有打开的文件描述符。在Linux中,一切皆文件(文件、目录、网络套接字等)。利用lsof工具,可以知道哪个进程正在使用某个文件或套接字

直接输入lsof命令,不带任何参数的时候,会列出所有被进程打开的文件

输出信息说明:

  • COMMAND: 运行进程的名称。PID: 进程的 ID。USER: 进程的所有者。

  • FD: 文件描述符,在进程内部唯一地标识了进程已打开的文件、套接字、管道或其他I/O资源。(在整个系统范围内不唯一;在进程范围内唯一)。如 cwd(当前工作目录)、txt(程序文本)等的描述符。

  • TYPE: 打开的文件的类型,如 REG(常规文件)、DIR(目录)、IPv4(IPv4 套接字)、mem(文件在内存中)

  • DEVICE: 设备编号,可以用来确定文件是存储在哪个硬盘分区或哪种类型的文件系统上

  • NODE: 文件的索引节点(inode)号。

  • NAME: 打开的文件的名称,对于网络套接字,这会是本地和远程的地址及端口

文件描述符说明:

文件描述符在单个进程内部唯一标识一个打开的文件或资源的整数。一个进程可以打开的文件描述符的数量是有限制的。这个限制可以通过 ulimit 或 limit进行设置。

如果要列出被特定用户打开的文件,通过 -u 参数可以实现

lsof -u user_name

如果想要查看特定进程打开的文件,通过 -p 参数可以实现

lsof -p PID

查找谁正在使用指定的文件或目录

lsof file_name

查找监听特定端口的进程:

lsof -i :port

说明:
NAME: 描述网络连接的来源和目的地。格式为 source->destination。
例如:

chrome  2979 ehigh   23u  IPv4 13208041      0t0  TCP ubuntu:34412->180.163.151.162:http (ESTABLISHED)
	# 表示连接的源地址是名为“ubuntu”的机器上的 34412 端口
	# 目标地址是 IP 180.163.151.162 上的 HTTP (端口 80) 服务。
	# 链接状态时活跃的

如果不想把IP地址解析为主机名,可以加 -n 参数来实现

查看所有的tcp或udp链接

# 列出所有使用 TCP 协议的网络连接
lsof -i tcp

#  列出所有 IPv4 协议的网络连接,不管是 TCP 还是 UDP
lsof  -i 4

# # 列出所有使用 UDP 协议的网络连接
lsof -i udp

lsof的使用场景:

端口冲突诊断: 一个应用程序报告说它无法绑定到某个端口,因为该端口已经被使用,那么可以使用 lsof 查找占用该端口的进程。

lsof -i :port

查找删除但仍被使用的文件: 如果删除了文件,但是硬盘空间没有被释放,就可以用这个查看

lsof命令会列出当前系统上所有打开的文件,然后使用grep工具过滤带有 (deleted) 标记的行,也就是被删除但仍然被进程引用的文件

lsof | grep delete

查找无法卸载的挂载点: 无法卸载某个文件系统,因为有进程正在访问它,找出来后kill掉指定进程就可以了。

lsof /path/to/mountpoint

网络连接分析: 一般用来分析哪个进程持有特定的套接字或端口

例如某个服务的端口被占用了,无法正常启动。这个时候如果使用ss或者netstat只能知道有一个进程正在监听,但是不知道是哪个进程。这个时候使用lsof -i :port就可以知道具体是哪个进程使用这个端口了。

lsof -i

kill和killall

信号用来实现管理员和进程之间的沟通,管理员通过指定的工具将信号发送给操作系统(操作系统同时管理了多个进程,为了区分不同的进程就使用 PID 来给进程编号。)操作系统接收到管理员发送的信号后,根据不同的信号来实现对进程的管理。

发送信号给一个进程,必须有相应的权限

  1. 如果用户ID与运行进程的用户ID相同,一般可以向该进程发送信号

  2. 向系统上的任何进程发送信号

  3. 非进程的所有者或超级用户,不能给进程发送信号


常用的信号说明

  1. SIGHUP信号(信号值:1):让进程重新加载配置文件(需要对应的程序支持接收到SIGHUP信号后做出处理),不会杀掉该进程

  2. SIGINT信号(信号值:2):用于终止进程,ctrl+c发送的就是这个信号

  3. SIGQUIT信号(信号值:3):退出程序,结束进程,作用类型于INT信号 ctrl+\

  4. SIGKILL信号(信号值:9):强制终止,不该操作是否完成

  5. SIGTERM信号(信号值:15):会让进程对应的操作完成后,正常终止

  6. SIGCHLD信号(信号值:17):让父进程发起系统调用,告诉操作系统回收僵尸进程

  7. SIGSTOP信号(信号值:18):暂停一个进程

  8. IGCONT信号(信号值:19):继续运行暂停的进程

  9. SIGTSTP信号(信号值:20):停止该进程的运行,CTRL+Z发出的就是TSTP信号


kill 命令使用说明

kill命令也是默认发送的15信号来优化的终止一个进程。

kill -信号值  PID

killall 命令使用说明

根据进程的名称发送信号给进程,不指定发送什么信号,默认发送的就是TERM来优雅的终止进程,实现一次性终止具有相同名称的多个进程

killall  -信号值 process_name

进程脱离终端运行

当我们在当前终端窗口创建一个进程时,该进程的父进程是当前窗口对应的shell。如果关闭当前窗口,子进程可能会被终止。为了确保进程在关闭窗口后继续运行,可以使用以下方法:

方法一:不响应 HUP 信号

在一个shell终端中创建一个进程后,该进程的父进程就是这个shell。当关闭终端时,HUP信号会发送给前台进程组。如果让这个子进程不响应HUP信号,当其父进程(即终端)结束时,它会变为孤儿进程,并最终被PID为1的进程接管。

nohup command &

nohup和&搭配使用的原因:

使用nohup命令启动一个进程会导致该进程在前台执行,通过 & 可以让前台进程变为后台进程,后台进程:在shell中启动,但不占据前台,允许用户继续与shell交互。后台进程的父进程仍然是当前shell

方法二:使用 setsid:

setsid 命令为进程创建一个新的会话,并确保进程成为该会话的领导者。成为会话领导者的进程没有控制终端,因此与任何终端脱离关联。 这样该进程不会收到从其原始终端发送的HUP信号。

setsid command

方法三:使用 screen:

screen 是一个终端复用器,它允许你创建多个窗口并在需要时重新连接。当你从一个 screen 会话中断开时,运行的进程不会终止。

 screen command

前台进程和后台进程的切换:

通过jobs命令就可以查看后台进程

通过fg、bg、kill、&等可以实现进程前后台的切换

例如:停止一个后台运行的进程

posted on 2022-07-15 08:46  背对背依靠  阅读(913)  评论(0编辑  收藏  举报