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 :

multiprocessing gestion de process


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 16
    Par défaut multiprocessing gestion de process
    Bonjour,

    Je cherche à faire démarrer différent Process dans un programme, jusque la ok, mais voici ce que je voudrais faire.

    Je fait un traitement (sur une image) que j'ai mis dans une fonction, celle ci reçois des paramètres et retourne un résultat.
    Le nombre d'images à traiter est différent à chaque fois, bien sur il est connu au moment de la création des différent Process, je voudrais pouvoir en traiter plusieurs en parallèle (5 en même temps par exemple).
    Donc lancer 5 Process en même temps OK, mais comment faire pour en lancer 5, quand un s’arrête en relancer un autre et ainsi de suite jusqu’à ce que j'ai tout traiter ?

    Il se peut que se soit tout con, mais j'ai pas une grande expérience en Python3.

    Je ne donne pas mes codes de test, pour ne pas influencer vos réponse :-)

    Si j'ai pas été claire ;-)

    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
    def Ftraitement( arg1, arg2 )
       #Fait le traitement voulu
       ...
       return resultat
     
     
    def Fatraier( NbImage )
       # recupere le non de chaque image a traiter
       ...
       # creation du pool 5 Process Ftraitement(image, ...)
     
       #Temps qu'il y a des image a traiter
          #Si un Process se termine
             #Traiter son résultat
             #Relancer un nouveau Process Ftraitement(image, ...)
    Ha et si en bonus le Process pouvais envoyer des "info" a celui qu'il l'a lancer pendant le traitement...

    Merci
    Stéphane

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

    Je vous suggère d'aller regarder la bibliothèque concurrent.futures..
    Elle permet de créer un Pool de N threads/process et de leur soumettre des opérations à réaliser (fonction à appeler).

    Citation Envoyé par stephbb75 Voir le message
    Ha et si en bonus le Process pouvais envoyer des "info" a celui qu'il l'a lancer pendant le traitement...
    La documentation vous donnes des méthodes à utiliser pour échanger des informations...
    A vous de voir laquelle vous semble la plus adaptée à votre cas...

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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 16
    Par défaut
    Salut wiztricks

    Citation Envoyé par wiztricks Voir le message
    Je vous suggère d'aller regarder la bibliothèque concurrent.futures..
    Merci, j'ai déjà été voir les doc (exemple) et tenté d'appliquer, avec cela j'ai toujours un tas d'erreurs du type "TypeError: cannot pickle '_tkinter.tkapp' object" et bien d’autre.

    Non, j'ai été voir pour cette erreur....

    Actuellement ce que l'ai réussit à faire fonctionner c'est avec "multiprocessing.Manager()" mais je pense que l'on peut faire différemment.

    Merci

    Steph

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

    Citation Envoyé par stephbb75 Voir le message
    Merci, j'ai déjà été voir les doc (exemple) et tenté d'appliquer, avec cela j'ai toujours un tas d'erreurs du type "TypeError: cannot pickle '_tkinter.tkapp' object" et bien d’autre.
    On ne peut pas faire n'importe quoi mais si vous ne montrez pas ce que vous avez essayé pas facile de savoir où çà pèche.
    Je peux juste vous donner un nième exemple (basique) qui marche:
    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
    from tkinter import *
    from concurrent.futures import ProcessPoolExecutor as PoolExecutor
     
     
    def task(n):
        print(n)
        time.sleep(0.1)
     
    counter = 0
     
    def do_start():
        global counter
     
        counter += 1
        p = executor.submit(task,counter)
     
     
    if __name__ == '__main__':
        executor = PoolExecutor(max_workers=2)
     
        root = Tk()
        Button(root, text="start", command=do_start).pack()
        mainloop()
    Comme il y en a déjà plein sur Internet, l'intérêt est plutôt limité.

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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 16
    Par défaut
    Bonjour,

    Merci pour l'exemple.

    Voici la solution que j'ai trouvé et qui me convient a peut prêt :

    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
    def fonc( param )
       ...
       Fait plein de truc
       ...
       return 
     
     
    ... Plein de code ...
     
    param=["param process1", "param process2", "param process3", ... ]
     
    with Pool(processes=4) as pool:
        for ret in pool.imap_unordered( fonc, param ):
            print(" un process a fini avec retour ret")
     
    Et la suite du code ...
    Ce qui me permet de lancer X processus (c'est le nombre d'entrée dans Param qui détermine le nombre de processus lancé), 4 sont exécutes en parallèle, et a chaque fois qu’un s’arrête je récupérer le résulta.

    Par contre, peut t'on utiliser une classe à la place d'une fonction ?

    Si je pouvais faire communiquer les process avec l’appellent se seras un vrais plus pour moi.
    Pour le moment je n'ai pas trouvé comment y arrivé avec Queues ou Pipe.

    Sinon j'ai bien trouvé pour avoir pleins d’erreur :-)

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    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 679
    Par défaut
    Citation Envoyé par stephbb75 Voir le message
    Par contre, peut t'on utiliser une classe à la place d'une fonction ?
    On fait ce qu'on veut tant qu'on respecte les lois de la physique.

    Dans le cas particulier, vous vous rendez compte que vous avez dans un seul script des instructions qui vont s'exécuter dans le contexte de processus différents.... Et que le comportement sera complètement différent si les processus sont créés via "fork" ou via un "spawn" (les méthodes de démarrage documentées).

    Donc oui on peut mais... il faut comprendre ce qu'il se passe sous le capot car c'est pas magique...

    Citation Envoyé par stephbb75 Voir le message
    Si je pouvais faire communiquer les process avec l’appellent se seras un vrais plus pour moi.
    Pour le moment je n'ai pas trouvé comment y arrivé avec Queues ou Pipe.
    Vu le problème que vous avez présenté au départ, je ne vois pas trop l'intérêt d'avoir des Queues.

    Pour le reste, quelque soit le boulot que vous voulez réaliser, il faut d'abord apprendre à maîtriser la technique que vous envisagez d'utiliser... Pas besoin d'être "expert", juste définir le cas d'utilisation et arriver à le prototyper pour en dupliquer la structure qui fonctionne sera "assez bien".

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

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 16
    Par défaut
    Salut,

    Citation Envoyé par wiztricks Voir le message
    ... Et que le comportement sera complètement différent si les processus sont créés via "fork" ou via un "spawn" ...
    Je suis sous Windows, donc uniquement spawn ci j'ai bien compris.

    Citation Envoyé par wiztricks Voir le message
    Vu le problème que vous avez présenté au départ, je ne vois pas trop l'intérêt d'avoir des Queues.
    Je voudrais simplement qu'en cour de traitement cela avertisse le père d’où il en est.
    Pour schématiser par exemple pouvoir faire avancer une barre de progression (c'est un exemple !)

    Steph

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

    Citation Envoyé par stephbb75 Voir le message
    Je voudrais simplement qu'en cour de traitement cela avertisse le père d’où il en est.
    La progression d'un tas de boulot découpé et exécuté en tranches pourrait être le nombre de tranches effectuées/total.
    Ça permet à l'utilisateur d'avoir une idée que çà avance et que c'est près du milieu, de la fin...
    Après si vous voulez en plus ajouter la progression de chaque tranche... vous voulez "mieux" avant d'avoir fait "assez bien"...

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

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 16
    Par défaut
    Bonjour,

    J'ai réussit a faire ce que je voulais.
    Le code n'est peut être pas super, mais j'ai pas trouver mieux (pour le moment ?)

    Voici un exemple fonctionnel du truc.

    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
    import multiprocessing
    from multiprocessing import Pool
    from time import sleep
     
    # Function pour process
    def procFunction1( param ):
        msgQueue = param[0]
        sleep_time = int(param[1])/2
        msgQueue.put("- Start process sleep "+str(param[1]) )
        sleep(sleep_time)
        msgQueue.put("/ Process sleep "+str(param[1])+" a moitier" )
        sleep(sleep_time)
        msgQueue.put("* End process sleep "+str(param[1]) )
        return param[1]
     
     
    if __name__ == '__main__':
        print("Debut du process parent")
     
        # Creation de la queue de message
        m = multiprocessing.Manager()
        messageQueue = m.Queue()
     
        #Creation des param pour la fonction executer dans le process
        param = [ (messageQueue,2), (messageQueue,5), (messageQueue,9), (messageQueue,12), (messageQueue,3), (messageQueue,1) ]
     
        print("Lancement des Process ....")
        with Pool(processes=4) as pool:
            for i in pool.imap_unordered( procFunction1, param ):
                while not messageQueue.empty():
                    print(messageQueue.get())
                print( "Retour = " + str(i) )
     
        print("Fin du process parent")
    On peut surement faire autrement et mieux, je ne sais pas.

    Steph

Discussions similaires

  1. Gestion de process (metier?)
    Par OcterA dans le forum Autres Solutions d'entreprise
    Réponses: 0
    Dernier message: 20/05/2013, 22h36
  2. gestion socket process votre avis
    Par seal3 dans le forum C++
    Réponses: 9
    Dernier message: 09/08/2010, 13h49
  3. Mettre fin à un shell lancé à partir d'un script (gestion des process id)
    Par sanchou dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 23/08/2008, 21h38
  4. Réponses: 17
    Dernier message: 02/02/2006, 12h03
  5. Gestion des process
    Par Oswald dans le forum C
    Réponses: 3
    Dernier message: 29/08/2003, 11h52

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