为什么我不能在 Linux 上终止这个进程?

9 linux bash process

问题

我想终止一个名为 raspivid(使用 Raspberry Pi 相机录制视频的程序)的进程,但我不能......

我是这样称呼它的:

#!/bin/bash

#Start recording...
raspivid -w 800 -h 600 -t 15000 -o $1 -v -n -rot 270 >> /home/pi/log/camera_output.txt 2>&1 &

#Waiting the video to be complete
sleep 16

#Killing child process
sudo kill -9 $!

#Killing parent process
sudo kill -9 $$
Run Code Online (Sandbox Code Playgroud)

如果我搜索这个过程,它仍然存在:

pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     7234  0 21:53 ?        00:00:00 [raspivid]
pi       17096 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid
Run Code Online (Sandbox Code Playgroud)

如果我试图杀死它,它不会死。相反,它将父 PID 更改为 1:

pi@raspberrypi ~ $ sudo killall raspivid
pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     1  0 21:53 ?        00:00:00 [raspivid]
pi       17196 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid
pi@raspberrypi ~ $ sudo killall raspivid
Run Code Online (Sandbox Code Playgroud)

观察:

  1. 通话可以正常工作一段时间(2 小时左右),然后开始挂起。
  2. 只有物理关机才能解决问题。我无法通过终端重启(它也挂了)

我的问题:

  1. 为什么 Linux 将父 PID 分配为 1?
  2. 为什么进程不能被杀死?(我也试过sudo kill -9 7238

Has*_*tur 2

问题

由于您的命令,您的脚本可能会创建僵尸kill -9;正如jjlin 答案所建议的那样,在不被迫的情况下突然终止某些进程也绝不是一个好习惯。

从中man bash我们可以读到:

标记为 <defunct> 的进程是死进程(所谓的“僵尸”),它们之所以保留,是因为它们的父进程没有正确地销毁它们。如果父进程退出,这些进程将被 init(8) 销毁。

答案#1:进程init 的PID为1,因此 Linux 为它们分配了 PID 1 的父进程(因为它将它们分配给init)。

答案#2:他们不能仅仅因为他们刚刚死了而被杀死......如果他们的父母init可能足以等待一段时间。

要从系统中删除僵尸,可以使用kill命令手动将SIGCHLD信号发送到父系统。如果父进程仍然拒绝收割僵尸进程,下一步就是删除父进程。当一个进程失去它的父进程时,init 就成为它的新父进程。Init 定期执行 wait 系统调用以获取以 init 作为父级的任何僵尸。[1]

以防有一天出现这种想法:使用 root 权限进行#kill -9 init处理相当于将计算机从电网上物理拔掉。[:-)]

但是,可以通过STAT列中是否存在“Z”来在命令的输出中识别僵尸进程。您可以使用以下行轻松识别它们ps

ps -aux | grep Z
Run Code Online (Sandbox Code Playgroud)

关于Linux 僵尸世界的一些参考资料: