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 :

Terminer proprement une boucle infinie


Sujet :

Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 1
    Points : 2
    Points
    2
    Par défaut Terminer proprement une boucle infinie
    J'ai un petit script python qui me permet d'automatiser certaines tâches (sauvegarder régulièrement mon travail sur un ordi distant, surveiller l'arrivée de nouveaux mails,etc). Mon script se lance automatiquement au démarrage de l'ordinateur (sous windows), et a la structure globale suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    import time
    while True:
       time.sleep(180)
       checkmail()
       filesynchro()
    Mon problème, c'est comment faire en sorte qu'à l'arrêt de la machine, mon script s'arrête proprement. Je suppose que l'OS envoie un signal au programme, mais lequel? comment l'intercepter et faire en sorte de quitter proprement? (c-à-d sans que l'OS me demande "forcer à quitter?" ou attende la fin du sleep ou tout simplement râââme...)

    Merci d'avance pour votre aide!

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 065
    Points : 1 403
    Points
    1 403
    Par défaut
    pitêtre en catchant l'exception que doit raise le kill.

  3. #3
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    En principe un truc du genre
    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
    import signal
    import time
    import sys
     
    def handler( signum,frame ):
        # stop checkmail
        # stop filesynchro
        sys.exit( 1 )
     
    signal.signal( signal.SIGTERM,handler )
     
    while True :
        time.sleep(180)
        checkmail()
        filesynchro()
    devrait marcher...
    mais là je n'ai pas eu trop le temps d'essayer.

  4. #4
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    il ne serait pas mieux de faire une fonction qui s'appelle elle même pour eviter de mettre en place une boucle infinie !!?

    genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import time
    var=0
     
    def main(var):
        if var<25:
            print var
            var+=1
        else:return
        time.sleep(1)
        main(var)
     
     
    if __name__ == '__main__':
        main(var)

    et puis on implante une variable qui permet de rompre l'exécution. Cette variable doit en effet renvoyer l'état du système.

  5. #5
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par airod Voir le message
    il ne serait pas mieux de faire une fonction qui s'appelle elle même pour eviter de mettre en place une boucle infinie !!?
    Euh ça c'est juste pire... Parce que c'est une récursion infinie, ce qui veut dire Stack overflow...

    Non la boucle infinie n'est pas le problème. Pour le signal de fermeture, sous Windows, c'est un WM_QUERYENDSESSION. Mais encore faut-il avoir un handle de fenêtre...

  6. #6
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Au départ j'avais penser à quelque chose comme ceci
    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
    import atexit
    import threading
    import time
    #import signal
     
    class Scrudtools(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.Terminated = False
     
        def run(self):
            while not self.Terminated:
                #checkmail()
                #filesynchro()
                time.sleep(180)
            # Post traitements
     
        @atexit.register # Ou utiliser signal
        def stop(self):
            self.Terminated = True
     
    if __name__ == "__main__":
        app = Scrudtools()
        app.start()
    Mais bien sur cela ne fonctionne pas car l'os n'en a rien à faire des états d'âme lorsque il force un arrêt.
    La solution que vous recherchez passe par un service (sous Windows) ou un deamon (linux) (mac ? J'y connais rien ) et l'interception de la demande d'arrêt.
    Vous trouverez des exemples dans ce sens sur le Web (là je vais manger ;p)

    @+

  7. #7
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Non la boucle infinie n'est pas le problème. Pour le signal de fermeture, sous Windows, c'est un WM_QUERYENDSESSION. Mais encore faut-il avoir un handle de fenêtre...
    Pourquoi passer par le WM ?

  8. #8
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par PauseKawa Voir le message
    La solution que vous recherchez passe par un service (sous Windows)
    Une piste (Edit : après nettoyage des imports bien sur)

    @+

  9. #9
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    comme j'ai dis une grosse bêtise dans mon post précédent, j'ai cherché un peu de doc a ce sujet.
    Je suis tombé sur cet article qui parle des fonctions récursives terminales.
    voici le lien :
    http://blog.fastconnect.fr/?tag=python

    attention, ce n'est pas dans un but de polémique mais informatif.

  10. #10
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Si cela te rassure airod ce genre de code est possible si tu fais appel à un callback externe .
    Exemple avec tkinter
    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
    import time
    import Tkinter as tk
     
    def cnt():
        newval = int(labvar.get()) + 1
        labvar.set(newval)
        root.after(100, cnt)
     
    root = tk.Tk()
    labvar = tk.StringVar()
    labvar.set('1')
    label = tk.Label(root, textvariable=labvar, fg="red")
    label.pack()
    tk.Button(root, text='Stop', command=root.destroy).pack()
    root.after(100, cnt)
    root.mainloop()
    @+

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    105
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 105
    Points : 145
    Points
    145
    Par défaut
    Bonjour,

    Je vais peut être dire une bêtise, mais pourquoi ne pas utiliser le gestionnaire de "Tâches planifiées" de Windows qui fonctionne a peu près de la même manière que cron sous Unix?

    Ton script exécute les différentes actions que tu lui as programmé, puis se termine et c'est à la tâche planifiée de le réveiller un peu plus tard.

    Et en plus cerise sur le gâteau, il n'y plus de boucle infinie. ^^

    Salutations.

    PS: Pour ma part chaque fois que la solution doit passer par une boucle infinie, j'essaie souvent de trouver une autre solution.

  12. #12
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Simple et sans parade. Bonne réponse.

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

Discussions similaires

  1. Terminer proprement une boucle d'écoute
    Par chicorico dans le forum C
    Réponses: 5
    Dernier message: 05/04/2012, 12h06
  2. Impossible de terminer une boucle infinie
    Par vincent tariel dans le forum Multithreading
    Réponses: 11
    Dernier message: 27/02/2012, 17h34
  3. Select qui fais une boucle infinie
    Par MaitrePylos dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 28/03/2006, 18h29
  4. Réponses: 10
    Dernier message: 24/12/2005, 16h35
  5. [FTP] comment corriger une boucle infinie ?
    Par sofybj dans le forum Langage
    Réponses: 8
    Dernier message: 08/11/2005, 15h49

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