Interruption sur événement: t° CPU

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

estelle
Raspinaute
Messages : 154
Enregistré le : jeu. 24 déc. 2015 17:14

Interruption sur événement: t° CPU

Message par estelle » ven. 12 mars 2021 10:51

Bonjour,

Je cherche une méthode afin de soulager mon prg principale
Afin d'éviter de rester dans une boucle pour extraire la température de la CPU, je cherche une solution un peu identique à celle des interruptions sur GPIO
Ainsi en cas de température trop haute, on déclenche une interruption pour générer une alarme
Voici mon code:

Code : Tout sélectionner

def Temp_CPU():
    #-Temperature & ventilation coffret 
    with open('/sys/class/thermal/thermal_zone0/temp', 'r') as ftemp:
        cpu_temp = int(ftemp.read()) / 1000
        print("Temperature CPU: ",cpu_temp,' C') 
    if (cpu_temp > temp_cof):      
        print ('Temp > 40')
        Alarme = 2
    if (cpu_temp <= (temp_cof - 10)):    
        print ('Temp ok') 
    
 while not GPIO.input(Pres_piece): 
      Temp_CPU()     
J'ai lu quelques articles sur Threads
Peut être la solution !
Qu'en pensez vous ?
A+

destroyedlolo
Raspinaute
Messages : 1583
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Interruption sur événement: t° CPU

Message par destroyedlolo » ven. 12 mars 2021 16:28

Coucou,
ca faisait longtemps :D

Ben déjà tu peux mettre une attente entre 2 scan. Normalement (je n'ai pas tester en python), ca fait passer ta tache en "waiting" et donc libère le CPU pour autre chose voir le met en économie.

Sinon, suivant la prise en charge du CPU par le kernel, il est possible de mettre des alarmes sur les températures, voir même d'y associé un iNotify.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

estelle
Raspinaute
Messages : 154
Enregistré le : jeu. 24 déc. 2015 17:14

Re: Interruption sur événement: t° CPU

Message par estelle » sam. 13 mars 2021 07:33

Bonjour estroyedlolo,

Oui je voudrait bien passer cette tache en secondaire et ainsi libéré la CPU mais je ne sais quelles solutions adoptés
Avec des Threads, j' ai déjà réussi à faire tourner des tempos en arrière plan mais comme je ne maitrise pas bien cette technique...
Tu peux m'en dire plus ?
A+

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Interruption sur événement: t° CPU

Message par Bud Spencer » sam. 13 mars 2021 09:58

Si tu veux un exemple en python il y a celui-là.

Bon ce n’est pas un bon exemple. Je ne fais pas de commentaire technique là-dessus mais ... non c'est vraiment pas un bon exemple :roll: ...
En Plus ca ne répond pas tout a fait a ta question puisqu'il ni a pas d'évènement la dedans. Faire tourner des thread est une chose (encore que pour le faire correctement c'est un poil plus complexe que ca) mais implémenter des évènements cross thread c'est une toute autre histoire et python n'est vraiment pas une bonne idée pour ce genre de chose surtout pour un débutant.

Sinon, tu peux aussi faire beaucoup plus simple et efficace avec beaucoup moins de code …
viewtopic.php?f=44&t=3033&p=37151#p37151
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

estelle
Raspinaute
Messages : 154
Enregistré le : jeu. 24 déc. 2015 17:14

Re: Interruption sur événement: t° CPU

Message par estelle » sam. 13 mars 2021 11:42

J'ai testé cela:

Code : Tout sélectionner

import threading
import time

stop_threads = False

class Temp_CPU (threading.Thread):
    # Parametres: preset => temperature alarme , 
               
    def __init__(self, preset):
        threading.Thread.__init__(self)
        self.preset = preset
        

    def run(self):
        while True:
          with open('/sys/class/thermal/thermal_zone0/temp', 'r') as ftemp:
            cpu_temp = int(ftemp.read()) / 1000
            print("Temperature CPU: ",cpu_temp,' C') 
          if (cpu_temp > self.preset):      
              print ('Temp > 40')
              Alarme = 2
          if (cpu_temp <= (self.preset - 10)):    
              print ('Temp ok') 
          time.sleep(5)       

T1 = Temp_CPU(40)   # 
T1.start()

while True:              
    print('thread T1')  
    if T1.is_alive():
        print("T1 is actif")      
    time.sleep(1)
Par contre je ne sais pas la charge que représente le thread sur la CPU
Y a t il des outils pour vérifier ?
A+

destroyedlolo
Raspinaute
Messages : 1583
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Interruption sur événement: t° CPU

Message par destroyedlolo » sam. 13 mars 2021 12:22

Coucou

Ca aurait été en C (++ ou pas), j'aurai pu te donner un tas d'exemple mais pas en Python que je ne pratique pas.
estelle a écrit :
sam. 13 mars 2021 07:33
Avec des Threads, j' ai déjà réussi à faire tourner des tempos en arrière plan mais comme je ne maitrise pas bien cette technique...
Je viens de trouver (a l'arache) ce tuto qui m'a l'aire pas trop mal : https://www.tutorialspoint.com/python3/ ... eading.htm
Il y a a la fois des thread, des attentes dedans et de la communication inter thread.
Te restera a déterminer l'interval le plus intelligent entre 2 mesures.

Certes, ca ne répond pas a ta question initiale sur les interruptions : si tu veux vraiment passer par elle, il faut que tu regardes du coté de inotify ... après avoir vérifier les trucs que je te disais plus haut ...
Mais hormis évidemment pour le plaisir de le faire, l'utilisation d'une tempo est largement suffisante.

Bon W.E.
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

estelle
Raspinaute
Messages : 154
Enregistré le : jeu. 24 déc. 2015 17:14

Re: Interruption sur événement: t° CPU

Message par estelle » dim. 14 mars 2021 06:31

destroyedlolo merci pour ton aide et le tuto

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Interruption sur événement: t° CPU

Message par Bud Spencer » dim. 14 mars 2021 13:11

estelle a écrit :
sam. 13 mars 2021 11:42
J'ai testé cela:
Mouais ... c’est le probleme des mauvais exemples, ça donne des mauvaises idées ...

Tu peux enlever l’évaluation T1. Is.alive(). Elle ne sert à rien pour la simple et bonne raison que T1 est forcément alive et c’est bien là le problème. Tout comme dans l’exemple cité, tu utilises une boucle sans condition explicite de sortie dans ton thread. Ça, quel que soit le langage utilisé et quoi que fasse ce thread, c’est la pire chose que tu puisses faire et je ne comprend meme pas que personne ne réagisse à ça (ça en dit long sur le niveau des intervenants …). A partir du moment où tu fais ça tu te condamnes à ne pas pouvoir arrêter ton thread secondaire autrement qu’en le tuant arbitrairement sans aucun contrôle sur son point de sortie. Dans l’exemple cité, le mec n’est meme pas conscient de ça puisque la seule sortie du programme qu’il a prévue c’est le shutdown, ce qui résout très facilement le probleme d’un programme qui se plante :lol:

Pour juste comprendre, mets texto le code que tu as posté dans un fichier .py et démarre-le . Puis quitte le en faisant un ctrl+c. Tu verras que ça ne te rendra pas la main et que ‘T1 is actif’ ne s’affichera plus. En revanche ça continuera de t’afficher les sorties écrites par T1. Si tu es en mode desktop et que tu as lancé ça dans une fenêtre console, il suffit de fermer la fenêtre pour tuer le process. Par contre si tu es en mode console et que tu n’as pas la possibilité de te connecter pour ouvrir une autre console pour faire un kill sur le process, le seul moyen de l’arrêter sera de rebooter.

Si tu veux utiliser un thread comme tu le fais, remplace au moins le ‘true’ dans le while de T1 par un boolean de portée globale. De la sorte, dans la procédure de sortie de ton programme tu peux remettre cette variable à false suivi d’un T1.joint(). C’est de la méthode de débutant, mais au moins tu auras la certitude que T1 sera terminé avant la fin du thread principale. C'est la base fondamentale du fonctionnement propre du multithreading. Tous les threads secondaires doivent etre terminés avant la fin du thread principale. Si cette règle n'est pas respectée => code poubelle !


Une autre chose. Tu parles d’interruption sur évènement. Déjà, il y a là-dedans2 concepts. Interruption est une chose, évènement en est une autre, mais … c’est sans importance ici. Je ne sais pas ce que tu veux faire au final, mais supposons que tu veuilles juste piloter un ventillo quand le cpu dépasse une certaine temperature : La, tu as 2 choix :

1 – Tu mets le code de pilotage du ventillo dans ton thread T1 (enfin .. Après l’avoir codé correctement …). Dans ce cas, il n’y a pas d’évènement, c’est ton thread T1 qui va gérer ça dans son coin sans aucune interaction avec le thread pricipal. C’est loin d’etre la meilleure méthode, mais ça reste ce qu’il y a de plus simple et pour une bricole, ça peut suffire.

2 – Tu code ton thread T1pour qu'il lève un évènement dans ton programme principal en cas de dépassement de temperature. Dans ce cas tu peux coder une fonction dans le thread principal pour piloter le ventillo. Ça c’est beaucoup plus propre puisque ça minimise le code exécuté dans T1 et ça empêche tout probleme de concurrence (partage de ressource commune entre les 2 threads). Ça c’est la bonne méthode mais forcement c’est beaucoup plus compliqué surtout avec un langage comme python…

Bon avec tout ça, j’ai loupé le thread de l’apéro moi :roll:
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

jelopo
Raspinaute
Messages : 307
Enregistré le : mer. 11 oct. 2017 10:23

Re: Interruption sur événement: t° CPU

Message par jelopo » dim. 14 mars 2021 18:02

Bonjour,

Plusieurs autres approches qui me semblent intéressantes sont présentées ici:
https://realpython.com/python-sleep

En espérant que ça puisse aider..

A+

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Interruption sur événement: t° CPU

Message par Bud Spencer » lun. 15 mars 2021 12:10

Des solutions, il y en a plein, le tout c’est d’en choisir une bonne en fonction du contexte du programme. On a vu qu’il était très facile de très mal codé un truc qui donne malgré tout "l’impression" de fonctionner (cf l’exemple cité) mais comme c’est truffé de bugs, c’est totalement inutilisable dans un autre contexte. Dans la page que tu as cité jelopo, tu remarqueras qu’à chaque fois que le type utilise des threads secondaires, il prévoit systématiquement une solution 'propre' de sortie de ceux ci et dans la procédure de sortie du thread principal (except), il attend bien que tous ses threads secondaires soient terminés avant de quitter (thread joint()).

Code : Tout sélectionner

def worker(arg):
	while not arg["stop"]: <= Condition explicite de sortie de la boucle
        ...
        time.sleep(1)
        

et en sortie 
except KeyboardInterrupt:
            info["stop"] = True <= valeur de portée globale indiquant au thread de sortir de la boucle au prochain tour
           ...
    
    thread.join() <= attente de fin du thread

Il y a toutefois un problème avec cette méthode ou l’on sleep() dans un thread. Si le délai est court, genre 1 seconde, ça va, mais imaginons que l’on veuille qu’un des threads secondaires exécute une tache quelconque toutes les 5 minutes par exemple. Dans ce cas, ce n’est plus adapté parce que quand on va demander la fermeture du programme, celui-ci sera bloqué en attente de la fin de la période sleep() de tous les thread secondaire, ce qui veut dire que dans cette hypothèse, le programme peut mettre jusqu’à près de 5 minutes pour se fermer proprement …
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Répondre

Retourner vers « Python »