为什么我不能在Linux上终止此过程?


8

问题

我想终止一个名为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 $$

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

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

如果我尝试杀死它,它不会死。而是将父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

观察结果:

  1. 通话正常工作了一段时间(2个小时左右),然后开始挂起。
  2. 只有关闭电源才能解决此问题。我无法通过终端重新启动(它也挂起)

我的问题:

  1. 为什么Linux将父PID分配为1?
  2. 为什么进程无法终止?(我也尝试过sudo kill -9 7238

Answers:


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]

万一这个想法有一天或一天​​出现:#kill -9 initroot特权进行处理的软件相当于将计算机从电网上拔下。[:-)]

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

ps -aux | grep Z

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


父PID为1的进程不是僵尸。一种方法得到这个家长当其父母之前就被杀死。因此,他killall显然是在杀死父母,而不是他想要的过程。
Barmar 2015年

<defunct>在他的ps输出中看到什么?这与这个问题有什么关系?
Barmar 2015年

@Barmar我没看见。不幸的是,问题并不总是在您要搜索的地方。顺便说一句,$!kill -9没有等待相机的后台处理... sleep 16kill -9父母之后,又突然地。闻到.zombie的气味... 闻到气味(:-)),您可以看到,随着ps -ef他的跟随,孩子仍然活着,但是父母被杀死了(-9)。
哈斯图

1
我认为您正在将孤立进程与僵尸进程混淆,但是它们是无关的。
Barmar 2015年

再次查看脚本:他kill -9自己的过程。它合理的假设它的死亡,<解散> ...更后的非有效呼叫sudo killall raspivid。甚至有可能raspivid产生自己的仍为孤立状态的子进程。顺便说一句,只需执行“ ps -aux | grep Z”即可查看它是否为僵尸,并且(足够)可以避免kill -9主脚本中的进程。
哈斯图

4

回答问题1:

当进程产生子进程时,每个子进程都有自己的PID。每个子进程的PPID(父进程的ID)是其父进程的PID。如果父进程死亡,则子进程将成为孤立进程。孤立进程由系统初始化进程自动拾取,该进程的PID为1。


0

该程序可能已打开了摄像头设备,并且通过强行杀死它,您尚未允许其正确清理,因此现在卡住了。

一些观察:

  • 除非您知道自己在做什么,否则通常不要以-9开头来终止程序。普通杀(没有选项)就可以了。
  • 根本不需要在脚本中进行任何杀死。您已经传递-t 15000给该程序来指定视频的长度,因此第一次杀戮应该没有必要。第二次终止也是不必要的,因为外壳程序到达脚本末尾时将自行退出。如果程序没有自动退出(应该退出),那么您还会遇到其他问题。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.