Parallelisation de programme en python

a marqué ce sujet comme résolu.

Bonsoir chers amis j’essaye de créer des applications en python en parallélisant les taches. Mais j’ai une question. Comment savoir qu’un thread a finis d’exécuter sa tache sans qu’il y est d’erreur?

Merci pour vos différentes réponses .

+0 -0

Et dans le contexte de Python et du GIL, le multi-threading ne t’apportera rien de parallèle. Tu auras bien plusieurs threads concurrents, mais jamais deux tâches qui seront simultanément en cours d’exécution.

Alors s’il s’agit d’attentes sur des entrées/sorties, les threads feront parfaitement l’affaire (mais des coroutines seraient je pense préférables), mais tu n’auras pas de parallélisme, il faudra pour cela utiliser des processus.

Han bon hein.

Mais comment savoir qu’un thread a terminer son exécution tout court?

melo96

Je vais être plus direct, sans préciser un minimum ce que tu es en train de faire, c’est une question beaucoup trop vague. En supposant que tu utilises threading, la seule chose qu’on puisse te dire en l’état, c’est de lire la documentation, en l’occurrence celle de threading.Thread.is_alive et celle de threading.Thread.join.

Ce n’est pas la première fois que tu poses une question très vague et qu’il faut te tirer les vers du nez pour finir par comprendre ce que tu essayes de faire…

Les threads (au sein d’un processus) en Python c’est du concurrentiel à cause du Global Interpreter Lock qui va forcer qu’un seul thread à tourner à chaque fois.

Si tu veux de la vraie parallélisation tu dois utiliser le module multiprocessing qui va créer des nouveaux processus python et utiliser pickle entre autre pour passer les informations nécessaires en interne puisqu’ils ne pourront pas partager la mémoire avec ton processus principal. Tu dois donc programmer ta parallélisation en considérant cette contrainte.

Multiprocessing embarque trois objets utiles: Queue, Process et Pool.

  • Process est un wrapper qui va te permettre de lancer une tâche et accéder aux propriétés de l’état du process (is_alive, …)
  • Queue te permet de passer des messages d’un process vers l’autre.
  • Pool te permet de lancer des tâches qui vont être distribués entre plusieurs workers (process).

La manière dont tu vas utiliser Queue te permettra de savoir si ton process a planté ou non. Tu peux par exemple attraper les exceptions et les mettre dans ta Queue pour que ton processus principal les récupère quand il pourra.

Multiprocessing, ou concurrent.futures, ou subprocess, ou threading, ou asyncio…

Le fait que tout ça, ce soit dans la lib standard (alors qu’en Python, There should be one, and preferably only one, obvious way to do it) devrait te mettre la puce à l’oreille: la réponse est bien plus compliquée que "utilise multiprocessing et pickle" (d’ailleurs pickle est tellement lent que ça aussi, ça se discute1).

La première chose à faire, déjà, c’est connaître la nature de ce que tu cherches à "paralléliser", et si j’utilise des guillemets, c’est parce qu’il y a au moins une chance sur deux que ton problème, que tu ne nous as toujours pas exposé (et ça commence à devenir gonflant cette manie de poser des questions dans le vide), ne requière pas de "vraie" parallélisation au niveau de Python.

Quand je lis tous les posts précédents qui parlent du GIL et qui s’y arrêtent, j’ai très envie de compléter ces réponses : non, le GIL n’est pas une frontière insurmontable, et il est parfaitement possible d’exécuter plusieurs threads en parallèle et meubler 500% de CPU dans un seul processus Python (ça m’arrive régulièrement) : tout dépend du code qui tourne dans ces threads. Mais encore, si ton code est susceptible de relâcher le GIL pour bosser, ça ne te dit pas si tu devais utiliser threading, ou concurrent.Futures, ou asyncio avec un ThreadPoolExecutor, parce que là aussi le choix le plus judicieux dépend de la nature de ton problème et de ta façon de concevoir sa solution.

Donc j’en reviens à la question de base que tout le monde t’a posé ou presque : ne fais pas comme d’habitude et décris-nous précisément ce que tu cherches à paralléliser au lieu de t’arrêter sur la première indication au doigt mouillé qui vient, sans quoi on ne peut absolument pas te répondre efficacement et tu risques d’implémenter un truc à la fois trop compliqué et peut-être bien plus lent qu’un code naïf sans parallélisation.


  1. Perso, depuis que j’ai découvert msgpack, c’est comme le jour où j’ai découvert redis : j’ai arrêté de me prendre la tête sur toute une classe de problèmes. Rapide, compact, ouvert, libre, supporte le binaire, dispo dans tous les langages de la terre et extensible à volonté. C’est devenu la base de tous les protocoles de communication/formats de fichiers que j’implémente. Alors ouais, ça demande un effort supplémentaire par rapport à Pickle, mais le gain en cpu/bande passante/compatibilité compense largement l’effort d’adaptation.

+1 -0

Okay excusé moi d’abord pour les questions sans précision et je vous explique mon problème.

L’objectif de mon application est de permettre aux utilisateurs de charger un fichier csv et moi en retour de faire des statistiques sur ce fichier en utilisant pandas, matplotlib etc.

Pour cela j’aimerais paralléliser les taches en utilisant plusieurs processus. Voici comment je compte procéder:

Mon programme principal va décomposer le fichier csv de l’utilisateur en plusieurs petits fichiers.

Ensuite ces fichiers seront transmis aux processus.

Ces processus ferons le travail et créons des fichiers csv sur le disque.

le programme principal va récupérer ces csv, les assemblés et nous donner le résultat final.

Merci pour tous vos suggestions qui me permettrons largement de m’améliorer tant au niveau code que au niveau organisation. :D

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte