Dlaczego nie mogę zabić tego procesu w systemie Linux?

8

Problem

Chciałbym zabić proces o nazwie raspivid (program, który nagrywa filmy za pomocą aparatu Raspberry Pi), ale nie mogę ...

Tak to nazywam:

#!/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 $$

Jeśli szukam tego procesu, nadal tam jest:

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

Jeśli spróbuję go zabić, to nie umrze. Zamiast tego zmienia nadrzędny PID na 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

Obserwacje:

  1. Połączenie działa przez chwilę dobrze (2 godziny lub coś), a następnie zaczyna się zawieszać.
  2. Tylko fizyczne wyłączenie zasilania rozwiązuje problem. Nie mogę zrestartować się przez terminal (również się zawiesza)

Moje pytania:

  1. Dlaczego Linux przypisuje nadrzędny PID do 1?
  2. Dlaczego proces nie może zostać zabity? (Próbowałem też sudo kill -9 7238)

źródło

Odpowiedzi:

2

Problem

Twój skrypt prawdopodobnie tworzy zombie z powodu twoich kill -9poleceń; jak sugeruje również odpowiedź jjlin, nigdy nie jest dobrą praktyką, aby nagle zabić jakiś proces bez konieczności.

Z man bashmożemy przeczytać:

Procesy oznaczone jako <zlikwidowane> to martwe procesy (tak zwane „ zombie ”), które pozostają, ponieważ ich rodzic nie zniszczył ich odpowiednio . Procesy te zostaną zniszczone przez init (8), jeśli proces macierzysty wyjdzie.

Odpowiedź # 1: Proces init ma PID 1 i dla tego Linuksa przypisuje im nadrzędny PID 1 (ponieważ przypisuje je do init ).

Odpowiedź # 2: Nie można ich zabić tylko dlatego, że są martwi ... jeśli ich rodzic initprawdopodobnie wystarczy, by poczekać.

Aby usunąć zombie z systemu, sygnał SIGCHLD można wysłać do rodzica ręcznie, używając polecenia kill. Jeśli proces nadrzędny nadal odmawia zebrania zombie, następnym krokiem byłoby usunięcie procesu nadrzędnego. Kiedy proces traci swojego rodzica, init staje się jego nowym rodzicem. Init okresowo wykonuje wywołanie systemowe wait, aby czerpać zombie z init jako rodzicem. [1]

Na wszelki wypadek ten pomysł powstaje jeden dzień lub innego: aby #kill -9 initproces z uprawnieniami administratora jest odpowiednikiem oprogramowanie fizycznie odłączyć komputer od sieci elektrycznej. [:-)]

Jednak procesy zombie można zidentyfikować w wyniku pspolecenia przez obecność „Z” w kolumnie STAT . Aby łatwo je zidentyfikować, możesz użyć następującego wiersza

ps -aux | grep Z

Niektóre odniesienia do świata zombie Linux :

Hastur
źródło
Proces z nadrzędnym PID 1 nie jest zombie. Proces pobiera tego rodzica, gdy jego rodzic zostanie zabity przed nim. Więc jego killallnajwyraźniej zabija rodzica, a nie proces, który chciał.
Barmar
Gdzie widzisz <defunct>w jego psdorobku? Co to ma wspólnego z tym pytaniem?
Barmar
@Barmar Nie widziałem. Niestety nie zawsze problemem jest dokładnie to, czego szukasz . BTW ze $!on kill -9nie czekając na proces tła z kamerą ... po sleep 16on kill -9do rodziców , nagle znowu. Pachniało .zombie ... Idąc za zapachem (:-)) widać, że po ps -eftym, co zrobił, dziecko wciąż żyje, ale rodzic został zabity (-9).
Hastur
1
Myślę, że mylicie procesy osierocone z procesami zombie, ale są one niezwiązane.
Barmar
Spoglądając ponownie na scenariusz: on ma kill -9swój własny proces. Rozsądne jest założenie, że został zabity i <nieistniejący> ... jeszcze bardziej po nieskutecznym połączeniu sudo killall raspivid. Możliwe jest nawet, że raspividspawnują własne procesy potomne, które pozostają osierocone. BTW wystarczy zrobić „ps -aux | grep Z”, aby zobaczyć, czy jest to zombie, czy nie, i powinno (wystarczająco), aby uniknąć kill -9procesu w głównym skrypcie.
Hastur
4

Aby odpowiedzieć na pytanie nr 1:

Kiedy proces odradza procesy potomne, każde z nich ma swój własny PID. PPID każdego dziecka (identyfikator procesu rodzica) jest PID ich procesu nadrzędnego. Jeśli rodzic umiera, procesy potomne są osierocone. Osierocone procesy są automatycznie pobierane przez proces inicjowania systemu, który ma PID równy 1.

glapworth
źródło
0

Program prawdopodobnie ma otwarte urządzenie kamery, a przez przymusowe zabicie go nie pozwoliłeś mu odpowiednio wyczyścić, więc teraz utknął.

Kilka uwag:

  • Na ogół nie jest dobrym pomysłem zabicie programu, zaczynając od -9, chyba że wiesz, co robisz. Zwykłe zabijanie (bez opcji) jest w porządku.
  • W skrypcie nie powinno być żadnej potrzeby zabijania. Przeszedłeś już -t 15000do programu, aby określić długość filmu, więc pierwsze zabójstwo powinno być niepotrzebne. Drugie zabicie jest również niepotrzebne, ponieważ powłoka sama się zakończy, gdy osiągnie koniec skryptu. Jeśli program sam nie wychodzi (tak jak powinien), masz inne problemy.
jjlin
źródło