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 :

Thread - Signal : Stop thread sur signal


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut Thread - Signal : Stop thread sur signal
    Bonjour à tous,

    J'ai un programme qui lance plusieurs Thread. Lorsque je lance un signal sur mon processus main je voudrais qu'il termine les threads.

    Mon problème est que mon programme intercepte bien les signaux mais uniquement si les threads n'ont pas été lancés.

    Pour plus de clarté, voici mon code simplifié :

    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
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import os
    import sys
    import signal
    import wiringpi2 as wiringpi
    import MySQLdb as mdb
    from time import sleep
    from threading import Thread
     
    def stop_programme(signal, frame):
    	print """STOP"""
    	sys.exit(0)
     
    signal.signal(signal.SIGINT, stop_programme)
     
    ...
    def Fonctions
    ...
     
    class Sequence(Thread):
    	"""Chaque séquence est envoyée en Thread pour permettre une exécution parallèle"""
    	def __init__(self, pinGPIO, sequenceList):
    		Thread.__init__(self)
    		self.pinGPIO = pinGPIO
    		self.sequence = sequenceList
    		self.stoprequest = False
     
    	def run(self):
    		"""Parcours la sequence pour écrire les états GPIO sur la pin donnée"""
    		while not self.stoprequest:
    			for index, elt in enumerate(self.sequence):
    				# wiringpi.digitalWrite(self.pinGPIO, elt[0])
    				print "Guirlande : %d" % self.pinGPIO
    				sleep(elt[1])
     
    	def terminate():
    		self.stoprequest = True
     
    try:
    	...
    	Début du programme
    	...
    	Lancement des Threads
    except Exception, e:
    	print repr(e)
    	sys.exit(1)
    Si quelqu'un aurait une solution pour résoudre mon problème ou une piste.

    Merci !

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Est-ce que tu conserve des références de tes threads ?

    Si oui, alors mets les dans une liste et tu pourras itérer sur cette liste pour stopper tes threads.

    Quelque chose dans ce 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
    16
    17
    18
    19
    20
     
    def stop_programme(signal, frame):
        global seqs
        for seq in seqs:
            seq.terminate()
        sys.exit(0)
     
    ...
    seqs = []
    try:
        seq = Sequence(*args)
        seq.start()
        seqs.append(seq)
     
        deuxième thread
        troisième thread
        etc
    except Exception, e:
    	print repr(e)
    	sys.exit(1)

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    Oui mes Threads sont déjà dans une liste et je voulais également faire ta solution de boucler dessus pour les terminer (cette boucle n’apparaît effectivement plus dans mon code du premier message car je testais à ce moment si le signal était intercepté et ce n'est pas le cas).
    Cependant, à partir du moment où mes Threads sont lancés, mon programme n'intercepte plus les signaux (hormis le -9 bien sûr)

    Sinon, est-ce que tu as une solution pour lancer justement cette boucle de fin des Threads ? Mon projet final et de pouvoir le contrôler depuis une interface web.

    Merci

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Vous avez 2 méthodes pour contrôler l'arrêt des threads.
    Chaque thread regarde si un Event a été positionné

    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
    import signal
    import time
    import threading
     
    done = threading.Event()
     
    def worker():
        while not done.is_set():
            time.sleep(0.2)
        print ('worker exits')
     
    def handler(signum, frame):
        print ('Signal handler called with signal', signum)
        done.set()
     
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(2)
     
    p = threading.Thread(target=worker)
    p.start()
     
    while not done.is_set():
        time.sleep(0.2)
    p.join()
     
    signal.alarm(0)
    Les threads sont déclarée "daemon".
    Dans ce cas, elles sont détruites lorsque le processus "main" sort:
    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
    import signal
    import time
    import threading
     
    def worker():
        while True:
            time.sleep(0.2)
     
    done = False
    def handler(signum, frame):
        global done
        print ('Signal handler called with signal', signum)
        done = True
     
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(2)
     
    p = threading.Thread(target=worker)
    p.daemon = True
    p.start()
     
    while not done:
        time.sleep(0.2)
     
    signal.alarm(0)
    Citation Envoyé par DaSiX
    Cependant, à partir du moment où mes Threads sont lancés, mon programme n'intercepte plus les signaux (hormis le -9 bien sûr)
    Ce n'est pas ce qu'est supposé faire Python.
    Quelle est la version, comment a-t-ellle été construite?
    Si les exemples que j'ai posté fonctionnent, il va falloir regarder ce que fait votre code (pour ignorer les signaux).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    Super ! Merci beaucoup wiztricks. J'ai utilisé ta 2ème solution avec les daemon car la 1ère laissait encore les Threads travaillé un peu avant de les interrompre totalement.

    Du coup je ne sait pas pourquoi mon programme n'interceptait plus les signaux, mais avec tes deux solutions je pense avoir une idée :
    - il y a une liste contenant tout les Threads à exécuté
    - une fois les tous Threads préparés, je boucle sur la liste pour faire les .start()
    - je reboucle ensuite sur cette liste pour faire les .join()

    Si j'en crois les 2 codes que tu m'as fournis, je pense que c'est les join() qui bloquent l'interception. Débutant en python, je m'étais basé sur ce tuto.

    Merci à tout les deux pour votre aide.

    Bonne continuation

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par DaSiX Voir le message
    Si j'en crois les 2 codes que tu m'as fournis, je pense que c'est les join() qui bloquent l'interception.
    Lorsque daemon=False, les .join n'ont pas à être appelés avant la sortie du programme.
    Et comme la sortie du programme est provoquée par la réception du signal, pas facile de vous suivre.

    Par contre, un thread ne se terminera qu'après avoir testé l'Event.
    La sortie du .join dépendra du temps mis entre 2 tests successifs (par le thread).

    daemon = True fonctionne a tous les coups mais, si le thread doit fermer proprement des canaux d'ES... c'est plus possible.
    A vous de voir.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. Signal entre threads
    Par Nymar dans le forum Débuter
    Réponses: 6
    Dernier message: 04/04/2013, 23h27
  2. Réponses: 5
    Dernier message: 15/03/2012, 10h55
  3. Synchronisation de Threads avec un systeme de signal/event
    Par Niklaos dans le forum Threads & Processus
    Réponses: 23
    Dernier message: 03/01/2010, 19h01
  4. [POSIX][SIGNAL] envoyer un signal a thread avec sigqueue
    Par Mokhtar BEN MESSAOUD dans le forum POSIX
    Réponses: 3
    Dernier message: 09/02/2006, 18h07

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