IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Retrouver les pid des process fils d'une commande.


Sujet :

Python

  1. #1
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut Retrouver les pid des process fils d'une commande.
    Bonjour,

    Je gère via un daemon et une appli python la programmation de taches (maintenance, mises à jours, sauvegardes etc...) sur un système linux.
    J'ai donc des process divers (scripts python, scripts shell, exécutables) lancés à des heures programmées et qui tournent en arrière plan.
    Ce que je souhaiterais c'est en contrôler la durée (pas les defunct que je gère d'une autre manière) et killer les process qui dures trop de temps.
    Le souci c'est que les scripts shell et python lancent d'autres process fils et je ne sais pas comment faire pour récupérer leurs pid...

    Voici en gros ce que je voudrais faire mais sans utiliser le ps (Attention aux âmes sensibles, c'est moche )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #! /usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    #
    from subprocess import Popen,PIPE
    from os import waitpid, popen, kill
    from time import localtime, sleep
    from sys import argv, exit
     
    ind = 0
    # utilisation python process.py xxHxx
    try:
        if argv[1][2:-2] == 'h' or argv[1][2:-2] == 'H':
            tempfin = int(argv[1][:-3]) * 60 + int(argv[1][-2:])
    except: exit(1)
    starttime = int(localtime()[3]) * 60 + int(localtime()[4])
    if tempfin < starttime:
        print 'Erreur dans la durée, l\'heure de fin est déjà passée.'
        exit(1)
    cmd = 'ls -R' # par exemple
    print 'Duree de depart ', starttime
    print 'Duree max : ', tempfin
    p = Popen(cmd, stdout=PIPE, shell=True)
    sts = waitpid(p.pid, 1)
    print "Lancement ok avec PID ",p.pid
    fils = popen('ps -Al | grep ' + str(p.pid))
    print 'Tous les PID :'
    listPID = []
    for lignes in fils:
        longl = len(lignes)
        print str(lignes [11:-(longl-15)])
        listPID.append(str(lignes [11:-(longl-15)]))
    while True:
        if tempfin > int(localtime()[3]) * 60 + int(localtime()[4]):
            ind += 1
            print 'En cour : pass' , ind
            sleep(1)
        elif tempfin == int(localtime()[3]) * 60 + int(localtime()[4]):
            print 'Fin par kill'
            for items in listPID:
                print 'Kill de ',items
                kill(int(items), 9)
            print 'Heure de fin :',str(localtime()[3]) + 'h' + str(localtime()[4])
            break
        else:
            print 'Fin normale'
            print 'Heure de fin :',str(localtime()[3]) + 'h' + str(localtime()[4])
            break
    exit(0)
    Une idée ? Merci d'avance.

  2. #2
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Est-ce que Popen.kill ne tue pas lui-même les processus enfants ?
    SI ce n'est pas le cas, tu peux passer par le process group id:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pid = <pid du processus à tuer>
    gpid = os.getgpid(pid)
    os.killpg(gpid, signal.SIGKILL) # Eventuellement SIGTERM
    Je n'ai pas testé ce code, vu que je n'ai pas de python sous la main pour l'instant.
    os.killpg n'est disponible que sous Unix hélas, mais puisque tu bosses justement sous linux...

    PS: Ta boucle est complètement illisible...
    Je te conseille d'utiliser un timestamp unix pour tempfin, ça simplifierait déjà tes tests.
    A vrai dire je pige rien à ta boucle, est-tu certain qu'elle soit correcte ?

    Je te garantis en tout cas que tu auras des soucis dans certaines conditions, car tu ne prends qu'une partie de la date (heure et minute je crois). Que se passerait-il si tu lances un truc à minuit moins une ?

    Aussi, analyse tes tests:
    si le temps n'est pas dépassé, on continue
    si on est arrivé pile au temps, on arrête brutalement
    sinon (autrement dit, si le temps est dépassé), on affiche que ça s'est terminé normalement.

    Le dernier test est donc complètement erroné, puisque d'une part il n'arrivera que si la condition qui arrête la boucle foire, et que d'autre part il affiche que tout s'est bien terminé sans même vérifier qu'il n'y ait plus de processus actif.

    Peut-être aurais-tu du faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    si le temps n'est pas dépassé
        s'il reste des processus actifs, on continue
        sinon, on quitte puisque tout s'est bien déroulé
    sinon, on tue

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Il me semble que le Popen.kill c'est du 2.6 minimum, j'ai des serveurs en 2.5 sur le parc.
    Le killpg(getpgid(p.pid), SIGKILL) fonctionne à merveille et je suis une courge d'être passer à coter.
    Merci Antoine_935.

    PS : Pour ce qui est de la boucle je me doute bien (voir l'avertissement avant le code). C'étais juste pour l'exemlpe et 'puisque cela tourne'... Je vais fignoler cela.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. retrouver les noms des contraintes d'une table
    Par Agoye dans le forum Access
    Réponses: 1
    Dernier message: 12/12/2007, 23h40
  2. Réponses: 2
    Dernier message: 05/02/2007, 10h19
  3. Retrouver les valeurs des paramètres des fonctions d'une DLL
    Par Bernard Martineau dans le forum Langage
    Réponses: 6
    Dernier message: 08/11/2005, 10h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo