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 :

Synchronisation de threads dans python


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Février 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur validation
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2019
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Synchronisation de threads dans python
    Bonjour,

    Je suis actuellement en train de développer un script python qui me permet d'éxécuter via SSH des commandes sur des machines à distance.
    La classe que j'utilise pour la connexion SSH est très proche de celle qu'il y a sur ce site : https://daanlenaerts.com/blog/2016/0...aramiko-shell/
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import threading, paramiko
     
    class ssh:
        shell = None
        client = None
        transport = None
     
        def __init__(self, address, username, password):
            print("Connecting to server on ip", str(address) + ".")
            self.client = paramiko.client.SSHClient()
            self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
            self.client.connect(address, username=username, password=password, look_for_keys=False)
            self.transport = paramiko.Transport((address, 22))
            self.transport.connect(username=username, password=password)
     
            thread = threading.Thread(target=self.process)
            thread.daemon = True
            thread.start()
     
        def closeConnection(self):
            if(self.client != None):
                self.client.close()
                self.transport.close()
     
        def openShell(self):
            self.shell = self.client.invoke_shell()
     
        def sendShell(self, command):
            if(self.shell):
                self.shell.send(command + "\n")
            else:
                print("Shell not opened.")
     
        def process(self):
            global connection
            while True:
                # Print data when available
                if self.shell != None and self.shell.recv_ready():
                    alldata = self.shell.recv(1024)
                    while self.shell.recv_ready():
                        alldata += self.shell.recv(1024)
                    strdata = str(alldata, "utf8")
                    strdata.replace('\r', '')
                    print(strdata, end = "")
                    if(strdata.endswith("$ ")):
                        print("\n$ ", end = "")
     
     
    sshUsername = "SSH USERNAME"
    sshPassword = "SSH PASSWORD"
    sshServer = "SSH SERVER ADDRESS"
     
     
    connection = ssh(sshServer, sshUsername, sshPassword)
    connection.openShell()
    while True:
        command = input('$ ')
        if command.startswith(" "):
            command = command[1:]
        connection.sendShell(command)
    J'aimerais que l'éxécution de mes commande soit séquentielle c'est à dire qu'avant d'éxécuter la commande suivante, on attende que celle en cours soit terminée.

    Pour cela j'avais pensé à utiliser un mutex. Je prend le mutex à l'émission de la commande (dans ma "boucle" principale) , et j'attends la réception d'un pattern particulié qui signifie la fin de ma commande (genre "root >") et de libérer le mutex à ce moment la, afin que la boucle principale puisse passer à la commande suivante.
    Cependant ca ne fonctionne pas. Soit mon programme se bloque au bout de la deuxième commande, soit il exécute toutes mes commandes d'un coup (sans forcémment laisser à une commande le temps de se finir).

    Je ne suis également pas très fan de la solution du shell interactif que j'utilse, mais c'est la seule que j'ai trouvé qui me garde l'environnement comme je veux (comme si j'étais moi même sur le shell en fait)

    Bref si quelqu'un a une idée je suis preneur

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Pour exécuter vos commandes de façon séquentielle, pourquoi lire et afficher tout ce qui arrive de façon asynchrone?

    Après pour passer à la commande suivante, il faut pouvoir attendre que la commande précédente soit terminée.
    Ce qui n'est pas facile à déterminer (on attend le prompt?). Mais on peut lancer à la suite de la commande, une commande "echo" qui retournera une ligne commençant par un pattern connu à l'avance.

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

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Pour autant que les threads soient une bonne solution, il est possible de faire intervenir plusieurs threads dans un ordre déterminé.

    Voilà un petit exemple avec 5 threads numérotés de 0 à 4, et qui ont chacun un traitement de durée aléatoire de 0.0 à 1.0s:

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import threading
    import time
    from random import random 
     
    ##############################################################################
    etat = -1 # contient le numéro du thread en cours de traitement
    verrou = threading.Lock() # verrou pour la variable etat
    nummax = 5 # nombre de threads
     
    ##############################################################################
    def traitement(num):
        global etat, verrou, nummax
        while True:
            with verrou:
                if etat==num-1 or (etat==nummax-1 and num==0): # condition de traitement
                    etat = num if etat==num-1 else 0 # mise à jour de etat
                    print("Traitement par le thread", num) # affiche le numéro du thread
                    time.sleep(random()) # simule une durée aléatoire de traitement
     
    ##############################################################################
     
    # création des threads
    mesthreads = []
    for i in range(0, nummax):
        mesthreads.append(threading.Thread(target=traitement, args=(i,), kwargs={}, daemon=True))
     
    # lancement des threads
    for i in range(0, nummax):
        mesthreads[i].start()    
     
    x = input()
    Ce qui affiche:

    Traitement par le thread 0
    Traitement par le thread 1
    Traitement par le thread 2
    Traitement par le thread 3
    Traitement par le thread 4
    Traitement par le thread 0
    Traitement par le thread 1
    Traitement par le thread 2
    Traitement par le thread 3
    Traitement par le thread 4
    Traitement par le thread 0
    Traitement par le thread 1
    Traitement par le thread 2
    Traitement par le thread 3
    Traitement par le thread 4
    ...
    ...
    Il s'agit ici d'un code de principe, mais on pourrait imaginer des conditions de traitement de chacun des threads plus complexes, portant par exemple sur les données à traiter, ou sur des méthodes de traitement. Par exemple, simuler le fonctionnement d'un atelier d'outillage.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

Discussions similaires

  1. [Serveur J2EE] Faire tourner un thread dans un serveur d'applications
    Par Pierre-Yves VAROUX dans le forum Java EE
    Réponses: 3
    Dernier message: 13/10/2005, 14h10
  2. création de plusieurs threads dans WinMain
    Par ChidoriRasengan dans le forum DirectX
    Réponses: 1
    Dernier message: 15/06/2005, 21h36
  3. Réponses: 1
    Dernier message: 23/05/2005, 15h52
  4. Thread dans une classe ?
    Par Sephi dans le forum Threads & Processus
    Réponses: 7
    Dernier message: 07/03/2004, 18h16
  5. Synchronisation de thread
    Par declencher dans le forum Langage
    Réponses: 2
    Dernier message: 07/01/2004, 10h28

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