Forum Linux.redhat Être notifié de la fin d'un process

Posté par .
Tags : aucun
3
7
déc.
2011

Bonjour,

Pour m'aider à superviser une appli, j'aimerai savoir s'il existe une technique permettant d'être notifié de la fin d'un process, sans avoir à faire constamment du polling, cad, sans utiliser de boucle infinie, ou des variantes de `watch'.

Je pourrais faire ça avec inotify, mais je ne sais pas si/où la table des process est exportée via le systeme de fichiers.

D'avance merci

F

PS: Un collègue bien intentionné m'a rappelé l'existence du builtin *sh "wait $PID" . Comme quoi, rtfm, mais lequel ;)
Celà dit, je poste qd meme au cas ou ça aide des gens, ou que vous avez mieux à me proposer!

  • # cgroups

    Posté par . Évalué à 2.

    C'est possible avec les cgroups, en définissant un release_agent et en activant le notify_on_release pour un cgroup où tu aura placé ton processus à surveiller.
    Voir /usr/src/linux/Documentation/cgroups/cgroups.txt

    • [^] # Re: cgroups

      Posté par (page perso) . Évalué à 2.

      L'OP est peut-être sous un OS sans cgroups et de plus il semble programmer en shell de Bourne.

  • # trap sigchld_handler SIGCHLD

    Posté par (page perso) . Évalué à 6.

    Lorsqu'un processus fils meurt (ou change de status), le parent reçoit SIGCHLD. En shell de Bourne tu peut remplacer le handler implicite (qui ne fait rien) par ton propre handler en faisant

    trap sigchld_handler SIGCHLD
    
    

    Les langages proposant une interface UNIX permettent en général de modifier les handler de signaux, donc tu peux utiliser cette technique avec pratiquement tous les langages.

    Tu trouveras plus détails sur la fin d'un processus fils dans les pages de man suivantes: signal(3), signal(2), sh(1).

    • [^] # Re: trap sigchld_handler SIGCHLD

      Posté par (page perso) . Évalué à 4.

      Les pages de man que je voulais citer sont en fait: signal(3), wait(2) et sh(1).

    • [^] # Re: trap sigchld_handler SIGCHLD

      Posté par . Évalué à 1.

      Super intéressant, mais j'ai l'impression que ça ne fonctionne que pour les process issus du meme process parent. Or, ce qu'il me faudrait, et qui, d'après les autres réponses, est faisable avec des variantes de ptrace/strace/perf/stap, c'est pouvoir surveiller un PID arbitraire, même s'il est issu d'un autre shell, bref, sans relation avec le process qui va gérer le monitoring. Si ça peut se faire en pur shell, ou avec des outils plus minimalistes "faits pour ça", ça serait plutôt pas mal, parce que les autres solutions me paraissent un peu surdimensionnées.

      • [^] # Re: trap sigchld_handler SIGCHLD

        Posté par (page perso) . Évalué à 2.

        Dans ce cas, le plus simple est d'adopter la stratégie suivante:

        • Pour chaque application à surveiller, tu crées un wrapper qui se charge de démarrer l'application et joue le rôle de senseur en écrivant les évènements liés à l'application qu'il observe dans un journal ou un pipe nommé, et en lisant ses ordres dans un pipe nommé si tu as besoin de ce genre de fonctions.

        • Tu crées une application shell surveillant effectivement tout tes wrapper, lisant leurs rapports et leur envoyant des ordres.

        N'oublie pas que les I/O sur les pipes nommés sont blonquantes si une seule des extrémités du pipe est ouverte. Tu peux aussi utiliser les signaux USR1 et USR2 comme élément de communication entre les processus.

        La solution exacte dépend de ton problème, si tu veux surveiller des applications lancées en dehors de ton framework, etc. Le plus simple est que tu lances ton programme de surveillance à l'initialisation du système, comme ça tu peux supposer dans tes wrappers que ton programme est en marche et définir un protocole simple pour la communication à base de pipes nommés entre les rappels et le surveillant.

        Si cela ne suffit pas à ce que tu t'en sortes, il faut nous donner plus de détails sur ce que tu veux faire exactement pour qu'on puisse t'aider. (Qui lance l'appli, quelle appli, quels sont tes degrés de liberté et tes contraintes, etc.)

  • # alternatives

    Posté par (page perso) . Évalué à 3.

    La manière traditionnelle et sans doute la plus appropriée dans la plupart des cas est effectivement d'utiliser waitpid(). Mais puisque tu as l'air de vouloir du Tim Toady...

    ptrace(2) te donnera un PTRACE_EVENT_EXIT quand le process surveillé se termine.

    SystemTap permet de faire des trucs comme ça :

    probe kprocess.exit {
            if (pid() == 42) {
                    printf("process exited\n")
                    exit()
            }
    }
    
    

    Il y a un PERF_EVENT_EXIT qui est émis et qui doit pouvoir être récupérable via perf mais je sais pas s'il est possible d'obtenir celui d'un process spécifique.

    pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

  • # si c'est lancé via le shell

    Posté par . Évalué à 3.

    Tu as l'air de dire que c'est lancé via le shell pourquoi pas simplement :
    $ mon-process ; notify-me

  • # mkfifo j'ai envie de dire

    Posté par (page perso) . Évalué à 1.

    lanceur.sh :

    [...]
    mkfifo /tmp/pipo
    $( sleep 2 && monScriptQueJeDoisAttendre.sh ) &
    printf -- 'Finish' > /tmp/pipo
    echo 'Terminé'
    [...]
    
    

    monScriptQueJeDoisAttendre.sh

    [...]
    read biloute < /tmp/pipo
    [...]
    exit 0
    
    

    Bon bien sûr, il faut trapper un peu les signaux pour la suppression du fifo. Mais bon c'est simple au moins.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.