问题
我想终止一个名为 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
观察结果:
- 通话在一段时间内工作正常(2 小时左右),然后开始挂起。
- 只有物理关闭电源才能解决问题。我无法通过终端重新启动(它也挂了)
我的问题:
- 为什么Linux将父PID分配为1?
- 为什么进程无法被杀死? (我也尝试过
sudo kill -9 7238
)
编辑:
艾科利是对的。 S 列显示 D:
0 D 0 11823 11819 0 80 0 - 0 down ? 00:00:00 raspivid
答案1
如果您运行ps -el
而不是运行ps -ef
,您将获得一个S
包含进程状态的列。我的猜测是该进程处于 state D
,这意味着不间断的等待。
换句话说,该进程被困在设备驱动程序的混乱部分,并且内核认为在设备驱动程序释放它之前杀死它是不安全的。有时,您会在与有问题的 NFS 服务器或有错误的设备通信的进程中看到这种情况。在这种情况下,它看起来像是在与视频捕获设备对话。
不幸的是,除了重新启动系统之外,没有什么灵丹妙药的方法可以将进程从 D-wait 中解除。您可以尝试使用 Solaris 命令truss
来查明程序在卡住之前做了什么,但您可能对此无能为力。您可能只是有一个有缺陷的设备驱动程序。
最后,父进程 pid 更改的原因1
是您killall
成功杀死了父进程。每当一个进程退出时,它的子进程都会被 pid 1 继承。为什么ps -f
父进程的行与 .pid 不匹配是一个小谜团grep
。