Почему я не могу убить этот процесс в 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)

источник

Ответы:

2

проблема

Ваш сценарий, вероятно, создает зомби из-за ваших kill -9команд; Как подсказывает jjlin, ответ тоже никогда не является хорошей практикой, чтобы внезапно завершить какой-либо процесс без принуждения.

Из man bashмы можем прочитать:

Процессы с пометкой <defunct> - это мертвые процессы (так называемые « зомби »), которые остаются, потому что их родитель не уничтожил их должным образом . Эти процессы будут уничтожены init (8), если родительский процесс завершится.

Ответ № 1: процесс init имеет PID 1, и для этого Linux назначает ему родителя с PID 1 (потому что он назначает их для init ).

Ответ № 2: Их нельзя убить просто потому, что они просто мертвы ... если их родителей, initвероятно, достаточно, чтобы подождать некоторое время.

Чтобы удалить зомби из системы, сигнал SIGCHLD можно отправить родителю вручную, используя команду kill. Если родительский процесс по-прежнему отказывается пожинать зомби, следующим шагом будет удаление родительского процесса. Когда процесс теряет своего родителя, init становится его новым родителем. Init периодически выполняет системный вызов wait, чтобы пожинать зомби с init в качестве родителя. [1]

Только в случае , если эта идея возникает тот или иной день: в #kill -9 initпроцесс с корневой привилегией является программное обеспечение эквивалентно физически отсоединить компьютер от электросети. [:-)]

Однако зомби-процессы могут быть определены в выходных данных psкоманды по наличию «Z» в столбце STAT . Вы можете использовать следующую строку, чтобы легко идентифицировать их

ps -aux | grep Z

Некоторые ссылки о мире Linux-зомби :

Hastur
источник
Процесс с родительским PID 1 не является зомби. Процесс получает этого родителя, когда его родитель убит раньше, чем он. Таким образом, он killall, очевидно, убивает родителя, а не процесс, который он хотел.
Бармар
Где вы видите <defunct>в его psвыводе? Какое это имеет отношение к этому вопросу?
Бармар
@ Бармар я не видел. К сожалению, не всегда проблема именно там, где вы ищете . КСТАТИ от $!он , kill -9не дожидаясь процесса фона с камерой ... после того, как sleep 16он kill -9с родителем , внезапно снова. Пахло .zombie ... После запаха (:-)) вы можете увидеть , что следующий ps -efон сделал, ребенок еще жив, но родитель был убит (-9).
Хастур
1
Я думаю, что вы путаете бесхозные процессы с процессами зомби, но они не связаны.
Бармар
Снова ищем сценарий: он kill -9свой процесс. Разумно предположить, что он убит и <не функционирует> ... даже больше после неэффективного вызова sudo killall raspivid. Возможно даже, что raspividпорождает свои собственные дочерние процессы, которые остаются сиротами. Кстати, достаточно сделать «ps -aux | grep Z», чтобы увидеть, зомби это или нет, и этого должно быть (достаточно), чтобы избежать kill -9процесса в основном скрипте.
Хастур
4

Чтобы ответить на вопрос № 1:

Когда процесс порождает дочерние процессы, каждый из них имеет свой собственный PID. PPID каждого дочернего элемента (идентификатор процесса родителя) является PID их родительского процесса. Если родитель умирает, то дочерние процессы становятся сиротами. Потерянные процессы автоматически выбираются процессом инициализации системы с PID 1.

glapworth
источник
0

Программа, вероятно, имеет открытое устройство камеры, и, принудительно убив его, вы не позволили ему очиститься должным образом, поэтому теперь оно зависло.

Несколько замечаний:

  • Обычно не стоит убивать программу, начиная с -9, если вы не знаете, что делаете. Просто нормальное убийство (без вариантов) это нормально.
  • Там не должно быть необходимости делать какие-либо убийства в вашем сценарии вообще. Вы уже перешли -t 15000в программу, чтобы указать длину видео, поэтому первое удаление должно быть ненужным. Второе уничтожение также не требуется, поскольку оболочка завершит работу самостоятельно, когда достигнет конца сценария. Если программа не выходит сама по себе (как и должно быть), то у вас есть другие проблемы.
jjlin
источник