Linux下有关进程 ID(PID)的知识点


1个月前 79次点击 来自 Linux

什么是进程 ID?

PID 代表 进程标识号(process identification),它在大多数操作系统内核(如 Linux、Unix、macOS 和 Windows)中使用。它是在操作系统中创建时自动分配给每个进程的唯一标识号。一个进程是一个正在运行的程序实例。

除了 init 进程外其他所有的进程 ID 每次都会改变,因为 init 始终是系统上的第一个进程,并且是所有其他进程的父进程。它的 PID 是 1。

系统正在运行的进程的 PID 可以通过使用 pidof、pgrep、ps 和 pstree 命令找到。

pidof、pgrep、ps 和 pstree 如何查看一个进程的父进程号

方法 1:使用 pidof 命令

pidof 用于查找正在运行的程序的进程 ID。它在标准输出上打印这些 id。为了演示,我们将在 Debian 9(stretch)系统中找出 Apache2 的进程 ID。

# pidof apache2

3754 2594 2365 2364 2363 2362 2361

从上面的输出中,你可能会遇到难以识别进程 ID 的问题,因为它通过进程名称显示了所有的 PID(包括父进程和子进程)。因此,我们需要找出父 PID(PPID),这是我们要查找的。它可能是第一个数字。在本例中,它是 3754,并按降序排列。

方法 2:使用 pgrep 命令

pgrep 遍历当前正在运行的进程,并将符合选择条件的进程 ID 列到标准输出中。

# pgrep apache2

2361

2362

2363

2364

2365

2594

3754

这也与上面的输出类似,但是它将结果从小到大排序,这清楚地说明父 PID 是最后一个。在本例中,它是 3754。

注意: 如果你有多个进程的进程 ID,那么在使用 pidof 和 pgrep 识别父进程 ID 时就可能不会很顺利。

方法 3:使用 pstree 命令

pstree 将运行的进程显示为一棵树。树的根是某个 pid,如果省略了 pid 参数,那么就是 init。如果在 pstree 命令中指定了用户名,则显示相应用户拥有的所有进程。

pstree 会将相同的分支放在方括号中,并添加重复计数的前缀来可视化地合并到一起。

# pstree -p | grep "apache2"

|- apache2(3754) -|-apache2(2361)

| |-apache2(2362)

| |-apache2(2363)

| |-apache2(2364)

| |-apache2(2365)

| \`-apache2(2594)

要单独获取父进程,请使用以下格式。

# pstree -p | grep "apache2" | head -1

|- apache2(3754) -|-apache2(2361)

pstree 命令非常简单,因为它分别隔离了父进程和子进程,但这在使用 pidof 和 pgrep 时命令不容易做到。

方法 4:使用 ps 命令

ps 显示活动进程的选择信息。它显示进程 ID(pid=PID)、与进程关联的终端(tname=TTY)、以 [DD-]hh:mm:ss 格式(time=TIME)显示的累计 CPU 时间、以及执行名(ucmd = CMD)。输出默认是未排序的。

# ps aux | grep "apache2"

www-data 2361 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start

www-data 2362 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start

www-data 2363 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start

www-data 2364 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start

www-data 2365 0.0 0.4 302652 8400 ? S 06:25 0:00 /usr/sbin/apache2 -k start

www-data 2594 0.0 0.4 302652 8400 ? S 06:55 0:00 /usr/sbin/apache2 -k start

root 3754 0.0 1.4 302580 29324 ? Ss Dec11 0:23 /usr/sbin/apache2 -k start

root 5648 0.0 0.0 12784 940 pts/0 S+ 21:32 0:00 grep apache2

从上面的输出中,我们可以根据进程的启动日期轻松地识别父进程 ID(PPID)。在此例中,apache2 启动于 Dec 11,它是父进程,其他的是子进程。apache2 的 PID 是 3754。

killall 、kill 、pkill三个命令之间的区别

kill是杀掉单个进程killall是杀掉所有同名进程pkill是杀掉一类进程或者某个用户的所有进程

一、kill命令

kill 命令的用途

kill 命令很容易让人产生误解,以为它仅仅就是用来杀死进程的。我们来看一下 man page 对它的解释:kill - send a signal to a process.从官方的解释不难看出,kill 是向进程发送信号的命令。当然我们可以向进程发送一个终止运行的信号,此时的 kill 命令才是名至实归。事实上如果我们不给 kill 命令传递信号参数,它默认传递终止进程运行的信号给进程!这是 kill 命令最主要的用法,也是本文要介绍的内容。

一般情况下,终止一个前台进程使用 Ctrl + C 就可以了。对于一个后台进程就得用 kill 命令来终止。我们会先使用 ps、top 等命令获得进程的 PID,然后使用 kill 命令来杀掉该进程。

kill 命令格式

使用kill -l命令列出所有可用的信号。

最常被使用的信号是1/9/15:

1(HUP):重新加载进程。
9 (KILL):杀死进程。
15(TERM):完美地停止一个进程。
kill pid //同下-15默认的安全停止进程
kill -15 pid //
kill -9 pid  //彻底杀死进程

使用信号 15 是安全的,而信号 9 则是处理异常进程的最后手段,这样结束掉的进程不会进行资源的清理工作,所以如果你用它来终结掉 vim 的进程,就会发现临时文件 *.swp 没有被删除。

二、killall命令

Linux killall (kill processes by name)用于杀死进程,与 kill 不同的是killall 会杀死指定名字的所有进程。kill 命令杀死指定进程 PID,需要配合 ps 使用,而 killall 直接对进程对名字进行操作,更加方便。

killall -9 mysql         //结束所有的 mysql 进程

三、pkill命令

pkill 命令和 killall 命令的用法相同,都是通过进程名杀死一类进程,除此之外,pkill 还有一个更重要的功能,即按照终端号来踢出用户登录。

pkill mysql         //结束 mysql 进程
pkill -u mark,danny //结束mark,danny用户的所有进程
w  //#使用w命令查询本机已经登录的用户
pkill -9 -t pts/1  //#强制杀死从pts/1虚拟终端登陆的进程

四、拓展命令

如果能看懂下面一系列命令,那么killall 、kill 、pkill三个命令之间的区别你也就了然于胸了。

1、pgrep命令:专门显示进程的进程号,相当于:

ps -aux | grep 进程名 | grep -v grep| awk '{print $2}' 

2、pidof命令:pid of xx进程,显示进程的进程号,同上pgrep。

3、组合命令的使用:

pgrep mysql | xargs kill -s 9
ps -ef | grep mysql | grep -v grep | awk '{print $2}' | xargs kill -9
kill -s 9 `pgrep mysql`

看到上面这三条命令的转换想到了什么吗,联想下pkill命令:pkill=pgrep+kill

pkill与kill在这点的差别是:pkill无须 “s”,终止信号等级直接跟在 “-“ 后面。之前我一直以为是 “-s 9”,结果每次运行都无法终止进程。

killall和pkill是相似的,不过如果给出的进程名不完整,killall会报错。pkill或者pgrep只要给出进程名的一部分就可以终止进程。

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1