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 :

passer thread "en premier plan" lors d'une exception IOError [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Par défaut passer thread "en premier plan" lors d'une exception IOError
    Bonjour à tous.

    Au sein de mon projet (lié à un Raspberry mais peu importe) j'ai le besoin de vérifier si un des composants est bien connecté pendant que mon programme tourne.
    Indirectement ce composant est relié à l'aide d'un câble et pourrait être débrancher par inadvertance.

    Pour cette partie seule j'ai fait ce petit bout de code (pas top mais ça marche, au passage si c'est dégueux et qu'il y a plus simple je prends) :

    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
    #!/usr/bin/python
    # -*- coding: latin-1 -*-
     
    import time
    import smbus
     
    verif = True
    while verif:
    #Essayer de faire une lecture du registre sur le bus i2c adresse 0x20
        try :
            val = smbus.SMBus(1).read_byte(0x20)
        except (IOError):
            error = True
            while error :
                try:
                    val = smbus.SMBus(1).read_byte(0x20)
                    error = False
                except (IOError):
                    pass
                time.sleep(0.02)
        time.sleep(0.02)

    Maintenant ce que j'ai besoin de faire :


    J'ai mon programme principal qui tourne pour mon IHM, à partir duquel je lance un thread avec le code ci-dessus.
    Il faudrait que tant que le "try" provoque une exception IOError, le thread se mette "au premier plan" et empêche le programme principal de fonctionner (que le programme soit en attente de reconnexion du câble en gros). Et le thread repart en tâche de fond tant que c'est connecté et mon programme reprend la main.

    Est-ce envisageable de façon pas trop compliquée?

    Merci d'avance.

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

    Citation Envoyé par esope60 Voir le message
    Est-ce envisageable de façon pas trop compliquée?
    Il faut voir comment est lancé votre "thread" (car ce que vous montrez n'en est pas un)... mais çà risque d'être compliqué.

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

  3. #3
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Par défaut
    En effet, alors admettons ce code pour simplifier mon besoin.
    Le programme principal tourne en boucle en attendant l'appui sur un bouton.
    Si appui, print OK.

    Et il faudrait que mon thread surveillant la connexion au semi-conducteur MCP en tâche de fond, empêche de faire tourner le programme principal si j'obtient un IOError.
    Je sais arrêter mon thread à partir du programme principal grace à la globale, mais je ne sais pas agir sur le principal à partir du thread et ne vois pas comment c'est possible.

    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
    #!/usr/bin/python
    # -*- coding: latin-1 -*-
     
    import time
    import smbus
    from threading import Thread
     
    import Adafruit_GPIO.MCP230xx as MCP
    #définir la variable 'mcp' adressée en 0x20
    mcp1 = MCP.MCP23017(address = 0x20, busnum = 1)
    #définir l'entrée pour1 interrupteur à l'état haut avec résistance de pull up
    mcp1.pullup(0, 1)
     
     
    verif = True
    def sequence():
        global verif
        while verif:
            try :
                val = smbus.SMBus(1).read_byte(0x20)
            except (IOError):
                error = True
                while error :
                    try:
                        val = smbus.SMBus(1).read_byte(0x20)
                        error = False
                    except (IOError):
                        pass
                    time.sleep(0.02)
     
            time.sleep(0.02)
     
     
    if __name__ == "__main__":
        Thread(target=sequence).start()
     
        appui = True
            while appui:
                #jaune
                if mcp1.input(0) == False :
                    print("OK")
                time.sleep(0.02)

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

    Deux programmes indépendants ne peuvent communiquer qu'en utilisant des mécanismes systèmes (sockets, pipes, fichiers,....) qui permettent l’échanges de messages.
    Une mécanique simple pourrait être que le processus qui surveille stocke au démarrage son PID dans un fichier et en cas d'erreur, il se laisse juste mourir. Le processus GUI ira, à intervalles réguliers, lire le fichier, vérifier que le process existe encore et se geler sinon.

    Si les programmes ne sont pas indépendants (c'est le processus GUI qui lance celui qui surveille ou bien le thread qui surveille est un thread du processus GUI), on peut envisager d'autres solutions.

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

  5. #5
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Par défaut
    Merci de ton aide.
    Je vois ce que tu veux dire.
    Que ce soit lire le PID ou lire une valeur dans un fichier si erreur (ça c'est de mon niveau), ok je comprends.

    Mais cela m'amène deux questions:
    -Quand le process "meurt", il faut bien le relancer quand le câble est rebranché pour surveiller de nouveau, il faudrait gérer ça à quel endroit ?
    -Dans mon programme principal, comment je peux lui dire de vérifier à intervalle régulier tout en exécutant le reste des commandes au fil de l'eau ? On en revient à encore un thread et je suis dans le même cas qu'au début ? non ? je m'emballe ?

    Merci

  6. #6
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Par défaut
    En gros voici mon programme de base, pas terminé mais on voit bien l'idée (j'en ai parlé avec toi il me semble y a quelques mois tu m'avais aidé pour le lancement aléatoire des différents .py

    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
    #!/usr/bin/python
    # -*- coding: latin-1 -*-
    from subprocess import call
    import random
    import pygame
     
    #vérifier que le câble entre les deux pupitres sont bien connectés. Sinon jouer un son d'instruction.
    ##pygame.mixer.init()
    ##    pygame.mixer.music.load("branchement.mp3")
    ##    pygame.mixer.music.play()
    ##    while pygame.mixer.music.get_busy() == True:
    ##        continue
     
    jouer = True
    while jouer :
        liste_scripts = ["module1", "module2","module3","module5", "module6","module7", "module8","module9", "module11"]
        #mélanger l'ordre des scripts
        alea = random.sample(liste_scripts,9)
        print(alea)
     
        #lancer les scripts dans l'odre défini par alea
        for i in range (0, len(alea)):
            call("python " + alea[i] + ".py")
        #puis toujours lancer les modules 4 et 10 en dernier
        call("python module4.py")
        call("python module10.py")
        print("gagné")
        #Trouver une combinaison d'interrupteurs pour refaire une partie ou arrêter et éteindre le raspberry
    Ce programme appelle des .py qui mettent en stand by le programme principal tant qu'ils ne sont pas terminés. Et dans ces .py j'ai des thread pour certains (exemple : le .py attend l'appui sur des boutons jaunes et rouge, et derrière un thread active des leds jaunes et rouge. Lorsque les boutons sont appuyés le thread s'arrête, le .py aussi, et on revient au programme principal pour lancer aléatoirement le prochain .py.
    Et le but c'est que peu importe si je me trouve dans mon programme principal ou dans un des .py, la vérification de la connexion doit tout le temps avoir lieu, et figer le programme là où je suis.

    Je ne sais pas si c'est assez clair mon explication.
    Merci d'avance

  7. #7
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Par défaut
    Je viens de trouver quelque chose, dans l'esprit de ce que tu expliquais, est-ce que ça marcherait ?

    1) thread de surveillance lancé depuis programme principal
    2) au lancement d'un .py écriture dans un fichier de son pid. Si aucun .py encore lancé, ecrire le PID du programme principal (car le câble peut aussi être débranché avant de commencer, il faut le vérifier)
    3) lorsque le thread provoque une erreur exécuter ça

    >>>import psutil
    >>> somepid = "lire_pid_dans_fichier"
    >>> p = psutil.Process(somepid)
    >>> p.suspend()
    Boucler jusqu'à reconnexion, puis:
    >>> p.resume()
    Relancer la surveillance

    L'idée me plaît mais question:
    Si depuis le thread je suspends le prog principal (qui a lui même initié le thread) est ce que ça va suspendre le thread associé ou il est indépendant ?
    Au pire au lieu d'un thread du coup je peux carrément lancer un .py de surveillance avant le programme principal.
    Qu'en penses-tu ?

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    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 762
    Par défaut
    Citation Envoyé par esope60 Voir le message
    Ce programme appelle des .py qui mettent en stand by le programme principal tant qu'ils ne sont pas terminés. Et dans ces .py j'ai des thread pour certains (exemple : le .py attend l'appui sur des boutons jaunes et rouge, et derrière un thread active des leds jaunes et rouge. Lorsque les boutons sont appuyés le thread s'arrête, le .py aussi, et on revient au programme principal pour lancer aléatoirement le prochain .py.
    Mouais, voilà une construction bien compliquée alors que vous pourriez faire cela plus simplement avec des fonctions. Ce qui permettrait aussi de ne pas avoir à passer par l'environnement système pour communiquer.

    Citation Envoyé par esope60 Voir le message
    Si depuis le thread je suspends le prog principal (qui a lui même initié le thread) est ce que ça va suspendre le thread associé ou il est indépendant ?
    J'ai la flemme d'ouvrir la documentation Linux et de tester pour vous...

    Ceci dit, il est toujours plus simple d'avoir un "boss" (le programme principal) et des subordonnés qu'on pourra contrôler, relancer,...
    Et puisque vous parliez de GUI, il est quand même plus simple de bloquer en affichant une popup qui demande de vérifier la connexion et continuera après l'action sur un Button.

    - 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: 2
    Dernier message: 24/05/2007, 13h39
  2. [Yahoo Widgets]Passer une appli au premier plan
    Par Jim_Nastiq dans le forum Windows
    Réponses: 4
    Dernier message: 26/03/2007, 11h07
  3. Passer mon application access en premier plan ?
    Par electrosat03 dans le forum Access
    Réponses: 2
    Dernier message: 10/01/2007, 16h30
  4. Réponses: 6
    Dernier message: 14/06/2006, 08h56

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