Pourquoi ne puis-je pas tuer ce processus sous Linux?

8

Problème

Je voudrais tuer un processus appelé raspivid (programme qui enregistre des vidéos à l'aide d'un appareil photo Raspberry Pi) mais je ne peux pas ...

Voici comment je l'appelle:

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

Si je recherche ce processus, il est toujours là:

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

Si j'essaye de le tuer, il ne meurt pas. Au lieu de cela, il change le PID parent en 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

Observations:

  1. L'appel fonctionne bien pendant un certain temps (2 heures ou quelque chose), puis il commence à se bloquer.
  2. Seule une mise hors tension physique résout le problème. Je ne peux pas redémarrer via le terminal (il se bloque aussi)

Mes questions:

  1. Pourquoi Linux attribue-t-il le PID parent à 1?
  2. Pourquoi le processus ne peut-il pas être tué? (J'ai aussi essayé sudo kill -9 7238)

la source

Réponses:

2

Problème

Votre script crée probablement des zombies à cause de vos kill -9commandes; comme le suggère jjlin, la réponse n'est jamais non plus une bonne pratique pour tuer brusquement un processus sans y être forcé.

De man bashnous pouvons lire:

Les processus marqués <défunt> sont des processus morts (appelés " zombies ") qui restent parce que leur parent ne les a pas détruits correctement . Ces processus seront détruits par init (8) si le processus parent se termine.

Réponse # 1: Le processus init a le PID 1 et pour cela Linux leur assigne le parent avec PID 1 (car il les affecte à init ).

Réponse # 2: Ils ne peuvent pas être tués simplement parce qu'ils sont juste morts ... si leur parent est initprobablement suffisant pour attendre un certain temps.

Pour supprimer des zombies d'un système, le signal SIGCHLD peut être envoyé manuellement au parent, à l'aide de la commande kill. Si le processus parent refuse toujours de récolter le zombie, l'étape suivante serait de supprimer le processus parent. Lorsqu'un processus perd son parent, init devient son nouveau parent. Init exécute périodiquement l'appel système wait pour récolter tous les zombies avec init comme parent. [1]

Juste au cas où cette idée se pose un jour ou l' autre: au #kill -9 initprocessus avec les privilèges de root est l'équivalent logiciel physiquement Débranchez l'ordinateur de réseau électrique. [:-)]

Cependant les processus zombies peuvent être identifiés dans la sortie de la pscommande par la présence d'un "Z" dans la colonne STAT . Vous pouvez utiliser la ligne suivante pour les identifier facilement

ps -aux | grep Z

Quelques références sur le monde des zombies Linux :

Hastur
la source
Un processus avec le parent PID 1 n'est pas un zombie. Un processus obtient ce parent lorsque son parent est tué avant lui. Donc, il killalltue apparemment le parent, pas le processus qu'il voulait.
Barmar
Où voyez-vous <defunct>dans sa pssortie? Qu'est-ce que cela a à voir avec cette question?
Barmar
@Barmar je n'ai pas vu. Malheureusement, le problème n'est pas toujours exactement là où vous recherchez . BTW du $!il kill -9sans attendre le processus d'arrière-plan avec un appareil photo ... après un sleep 16il kill -9le parent , brusquement à nouveau. Ça sentait le .zombie ... Suite à l'odeur (:-)) vous pouvez voir qu'avec ce ps -efqu'il a fait, l'enfant est toujours vivant, mais le parent a été tué (-9).
Hastur
1
Je pense que vous confondez les processus orphelins avec les processus zombies, mais ils ne sont pas liés.
Barmar
En regardant à nouveau le script: il a kill -9son propre processus. Il est raisonnable de supposer qu'il est tué et <défunt> ... encore plus après l'appel non effectif sudo killall raspivid. Il est même possible que raspividses propres processus enfants soient orphelins. BTW il suffit de faire "ps -aux | grep Z" pour voir s'il s'agit d'un zombie ou non, et cela devrait être (assez) pour éviter kill -9le processus dans le script principal.
Hastur
4

Pour répondre à la question numéro 1:

Lorsqu'un processus engendre des processus enfants, les enfants ont chacun leur propre PID. Le PPID de chaque enfant (id de processus parent) est le PID de leur processus parent. Si le parent décède, les processus enfants sont orphelins. Les processus orphelins sont automatiquement récupérés par le processus d'initialisation du système qui a un PID de 1.

glapworth
la source
0

Le programme a probablement l'appareil photo ouvert, et en le tuant de force, vous ne lui avez pas permis de nettoyer correctement, alors maintenant il est bloqué.

Quelques observations:

  • Ce n'est généralement pas une bonne idée de tuer un programme en commençant par -9 sauf si vous savez ce que vous faites. Juste une mise à mort normale (sans options) est très bien.
  • Il ne devrait pas du tout être nécessaire de tuer dans votre script. Vous avez déjà passé -t 15000au programme pour spécifier la durée de la vidéo, donc le premier kill ne devrait pas être nécessaire. Le deuxième kill est également inutile car le shell se terminera de lui-même lorsqu'il atteindra la fin du script. Si le programme ne se termine pas de lui-même (comme il se doit), vous avez d'autres problèmes.
jjlin
la source