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 :

[Conseil] Diviser des tâches - Module multiprocessing


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut [Conseil] Diviser des tâches - Module multiprocessing
    Bonsoir tout le monde.


    J'ai actuellement une fonction lourde et mal optimisée. Mais je bosse déjà là dessus et je pense que malgré tous mes efforts le temps d'exécution restera conséquent (ça se chiffre en minutes...au moins). Mais c'est une autre histoire. Cette fonction doit être appelée un nombre conséquent de fois. Je pense que diviser les tâches en plusieurs processus indépendants est particulièrement indiqué dans ce cas (vous pouvez me détromper, il n'y a pas de soucis).

    J'ai fait quelques recherches sur le module multiprocessing de python. Mais je ne suis jamais tombé exactement sur ce que je cherche. Voici mon besoin: admettons que j'ai une liste de tâches à effectuer, un nombre inconnus nécessitant une durée d'exécution inconnue. J'aimerais pouvoir simplement lancer en parallèle un nombre défini de processus et ainsi traiter l'ensemble des tâches. Dans l'idéal, une fois une tâche de finie une autre se lance même si les autres tournent toujours. Mais il faudrait qu'il n'y jamais plus de n processus en même temps.

    Je ne crois pas au père noël, ça doit très sûrement existé. Mon petit doigt me dit d'utiliser pool(), mais les exemples que j'ai pu lire ne m'ont pas convaincus.


    Pour le moment je suis parvenu à bricoler quelque chose qui traite mes tâches par blocs de n processus. C'est déjà pas mal même si pas très académique:

    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 multiprocessing import Process, Manager
    import time
    import random
     
    def heavy_func(case_id, jobs_done):
        """Dummy heavy function"""
        time.sleep(random.randint(1,10))
        jobs_done[case_id] = 'Done'
     
    if __name__ == '__main__':
     
        jobs_to_do = ['Case%i' % (i,) for i in range(10)]
        jobs_done = Manager().dict()
     
        n_procs = 2
        procs = [Process(target=heavy_func, args=(c, jobs_done)) for c in jobs_to_do]
        for i in range(0, len(jobs_to_do), n_procs):
            for p in procs[i:i+n_procs]:
                p.start()
            for p in procs[i:i+n_procs]:
                p.join()
     
        print jobs_done
    J'utilise ici Manager() pour partager entre les processus un même dictionnaire. Actuellement mes résultats sont sortis sous cette forme, donc ça m'arrange bien.


    Ju

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

    Compte tenu de la syntaxe de vos print, vous travaillez avec Python2.
    Python 3.2 introduit le module concurrent.futures qui encapsule les fonctionnalités des modules threading et multiprocessing pour réaliser facilement le mapping de N taches sur M process, N > M.
    Plein d'exemples traînent sur Internet et dans la doc.
    Il existe aussi un backport de ce module pour Python 2.

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

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Salut,

    Merci Wiztricks, je ne connaissais pas concurrent.futures. Je vais étudier la doc pour voir si je trouve mon bonheur.

    Effectivement, j'aurais du mentionné que je bosse avec Python 2.7, c'est important. Je ne peux malheureusement pas encore migrer vers une version 3.* pour causes professionnelles. En faisant des recherches je suis tombé sur des modules comme asyncore, mais j'en ai pas lu que du bien.

    J'ai vu dernièrement qu'avec la version 3.4 vient asyncio qui doit rendre la programmation asynchrone plus aisée. Mais là encore je n'y ai pas droit...

    Mon besoin est tout de même simple, je pense m'en sortir avec uniquement les libs standards. Je ne cherche pas à faire des calculs distribués sur plusieurs machines en réseau.

    Je vais essayer de pondre un truc moi-même, mais si quelqu'un à un exemple de prêt je suis preneur.


    Ju

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

    asyncore est plutôt oriente protocole réseau. En dessous ca multiplexe select ou equivalent. C'est mono-threads.
    Je ne vois pas trop le rapport avec (ce que j'ai compris de) votre besoin.

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

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Par défaut
    Hello,

    Deux idées comme ça en passant, qui pourraient peut-être faire le taf (sans garantie, je suis pas très au point sur ce genre de probleme).

    Option 1: Un sémaphore, que chaque sous-process doit acquérir pour lancer son job. Tous les sous process sont lancés en même temps, mais seulement le nombre voulu sont en fonctionnement à un instant T

    Option 2: Même principe que 1, sauf que chaque lancement process est encapsulé dans un simple thread, qui lui lancera le sous-process lorsqu'il aura acquis le sémaphore. Ça devrait permettre une meilleure répartition sur les différents processeurs.

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

    Citation Envoyé par Petibidon Voir le message
    Option 1: Un sémaphore, que chaque sous-process doit acquérir pour lancer son job. Tous les sous process sont lancés en même temps, mais seulement le nombre voulu sont en fonctionnement à un instant T

    Option 2: Même principe que 1, sauf que chaque lancement process est encapsulé dans un simple thread, qui lui lancera le sous-process lorsqu'il aura acquis le sémaphore. Ça devrait permettre une meilleure répartition sur les différents processeurs.
    Sur le papier ca fonctionne mais je trouve que c'est un peu lourd car (1) cree N process qui ne foutent rien (mais qui consomment de la ressource) en attendant d’acquérir le sémaphore. (2) est encore plus lourd puisqu'on encapsule
    cela avec des threads.
    concurrent.futures (voir les sources) crée un seul thread qui gère une queue.Queue (un objet Python derrière lequel se cache un sémaphore) des taches en attente et s'occupe de démarrer la tache suivante des qu'un slot (process ou thread se libère).
    L'avantage est qu'on n'a pas a coder l'infrastructure qui gère le dispatch des N taches sur M process ou threads, ni la réalisation des interfaces qui vont bien.

    - 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. Faire clignoter la barre des tâches
    Par SteelBox dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 18h16
  2. Comment masquer le MessageBox de la barre des tâches ?
    Par Coussati dans le forum Langage
    Réponses: 7
    Dernier message: 25/08/2003, 14h33
  3. HAUTEUR de la barre des tâches de Windows ?
    Par Lung dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 13/12/2002, 11h43

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