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 :

tuer un thread dans un mainloop tkinter qui accede a une variable de la fenetre [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut tuer un thread dans un mainloop tkinter qui accede a une variable de la fenetre
    Bonjour:

    Mon but c'est de tuer un thread qui interagit avec des variables d'une fenêtre tkinter. Dans mon vrai programme, ce thread lit la température du CPU et asservi d'autre threads (de multiprocessing cette fois) qui sont charger de faire chauffer le CPU
    jusqu’au la température de consigne. Cela permet à l'utilisateur d'entrer la température à partir de laquelle l'ordinateur devient bruyant. Suite à ça, un autre programme se bridera de façon à ne pas excéder cette température, en effet, la nuit l'ordinateur fait du potain si il tourne à fond.
    Avec cette technique, j'aimerai pouvoir le faire travailler au maximum sans pour autant qu'il fasse de bruit... Voila pour le contexte.
    Après réduction à un code minimal cela donne:
    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 tkinter
    import threading
     
    class MonThread(threading.Thread):
    	def __init__(self, var):
    		threading.Thread.__init__(self)
    		self.var = var
    		self.sucide = False
     
    	def run(self):
    		while not self.sucide:
    			self.var.get()
     
    def quit():
    	thread.sucide = True
    	# thread.join(timeout=0)
    	fenetre.quit()
     
    fenetre = tkinter.Tk()
    tkinter.Button(text="quit", command=quit).pack()
    var = tkinter.StringVar()
    thread = MonThread(var)
    thread.start()
    fenetre.mainloop()
    Je pense avoir identifié le problème mais je ne sais pas comment le résoudre. Je m'explique:
    au moment du '.mainloop', j'imagine qu'un thread est lancé car il est en écoute des éventements.
    quand un éventement se produit, se thread 's'arrette' ou du-moins pose un verrou car il se fige. (Ce que je veux dire c'est que par exemple si un bouton exécute une fonction un peu longue, la fenêtre ne réagit plus à rien tant que la fonction n'a pas retournée.)
    Ducoup, dans cet exemple, quand on appel quit, tout devient inaccessible, dont la variable 'var'. le programme se bloc donc a la ligne 'self.var.get()' qui doit attendre un verrou qui ne sera pas libéré avant de sortir de 'quit()'...

    Ce n'est qu'une supposition et c'est peu être complètement faux ce que je raconte

    J'ai essayé le .join(timeout=0) mais c'est sans succès.
    Je me suis dit que lancer la fonction 'quit' dans un autre thread pourrait résoudre le problème car la fenêtre principale ne serai pas verrouillé, mais je ne sais pas trop comment mettre ça en place et ça me parait bien compliqué...

    Est-ce que le problème est bien celui que j'imagine? Il y -t-il un moyen d'y remédier?

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    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 743
    Par défaut
    Salut,

    Citation Envoyé par robinechuca Voir le message
    Est-ce que le problème est bien celui que j'imagine? Il y -t-il un moyen d'y remédier?
    A priori, vous démontrez juste que tkinter n'est pas thread friendly (i.e. vous avez intérêt à effectuer le minimum d'opération tkinter en dehors du thread tkinter).

    Après si la question est comment expédier un objet à un thread, pour çà vous avez des "Queues".

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

  3. #3
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut
    Heu, de ce que j'ai l'impression de comprendre 'Queue' permet de mettre en place des files qui peuvent être partagée entre différent threads.
    Hors problème d'implémentation (ça je devrai pouvoir m'en sortir tous seul) je ne comprend pas conceptuellement en quoi ça résout le problème .
    Merci quand même pour la piste, des fois que ça m'inspire une idée fulgurante

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    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 743
    Par défaut
    Salut,

    Citation Envoyé par robinechuca Voir le message
    je ne comprend pas conceptuellement en quoi ça résout le problème
    Une queue est "partageable". On peut faire des .put (ajout d'objets dans...) et des .get (retirer un objet de...) depuis des threads distinctes.

    Une Variable tkinter n'est accessible que depuis le thread dans lequel tourne tkinter. Vous allez dire "oui mais çà marche jusqu'à ce que je stoppe le thread donc il n'est pas interdit de..."
    Ce qui est vicieux dans les objets partagés entre plusieurs threads c'est que le bon fonctionnement du truc dépend du "timing". Dit autrement, çà fonctionne dans une certaine fenêtre temporelle, faites glissez la fenêtre et çà cafouille.
    Chez moi, j'ai reproduit facilement le problème avec le code que vous avez posté. Modifiez légèrement le code avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
             def run(self):
    		while not self.sucide:
    			self.var.get()
                            time.sleep(0.001)
    Çà va retomber en marche juste parce qu'on casse la fenêtre.

    Mais ce n'est pas une solution, juste un exemple qui montre la fragilité d'un code qui suppose que tkinter supporte les threads.

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

  5. #5
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut
    Pour forcer les fenêtres à avoir le bon décalage, suffit-il d’empêcher l'utilisateur de cliquer au mauvais moment?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    def run(self):
    	while not self.sucide:
    		boutton.configure(state="disable")
    		self.var.get()
    		boutton.configure(state="normal")
    		time.sleep(0.001)
    Il semblerai que ça fonctionne mais c'est pas folichon dans le principe.

    Ce qui me bloque avec Queue, c'est que je ne vois pas comment introduire le .put puisque c'est un tkinter.Entry qui fait office de '.put'. Encore dans ce sens la je peux peut-être m'en sortir en passant par une variable intermédiaire.
    Mais dans le 'vrai' code, je fonctionne aussi en sens inverse: le thread change une variable affin de changer l'affichage d'un Label. Et dans ce sens là, c'est plus compliqué car c'est le '.get' qu'est géré par tkinter.

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    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 743
    Par défaut
    Citation Envoyé par robinechuca Voir le message
    Pour forcer les fenêtres à avoir le bon décalage, suffit-il d’empêcher l'utilisateur de cliquer au mauvais moment?
    Il semblerai que ça fonctionne mais c'est pas folichon dans le principe.
    C vous montre que la mécanique est instable et qu'on ne peut pas l'utiliser comme çà.
    Dans la littérature, on dit que ce n'est pas thread-safe.

    Ce qui me bloque avec Queue, c'est que je ne vois pas comment introduire le .put puisque c'est un tkinter.Entry qui fait office de '.put'. Encore dans ce sens la je peux peut-être m'en sortir en passant par une variable intermédiaire.
    Mais dans le 'vrai' code, je fonctionne aussi en sens inverse: le thread change une variable affin de changer l'affichage d'un Label. Et dans ce sens là, c'est plus compliqué car c'est le '.get' qu'est géré par tkinter.
    Je suis d'accord qu'il va falloir revoir un certain nombre de choses.
    Vous pourriez regarder tkthread (et les autres bibliothèques mentionnées) supposées résoudre le problème.

    - 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. Réponses: 3
    Dernier message: 10/08/2007, 13h42
  2. fonction qui indique qu'une variable est d'un type entier
    Par piotrr dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 21/06/2007, 16h05
  3. Valeurs qui disparaissent d'une variable session (tableau)
    Par Pansatyros dans le forum Langage
    Réponses: 3
    Dernier message: 09/05/2007, 11h18
  4. Réponses: 3
    Dernier message: 20/11/2006, 09h45
  5. Accéder à une variable dans un iframe
    Par bodygard dans le forum ASP.NET
    Réponses: 3
    Dernier message: 10/03/2006, 10h43

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