32 votes

multiprocessus ou threading en python ?

J'ai une application python qui saisit une collection de données et pour chaque donnée de cette collection, elle exécute une tâche. Cette tâche prend un certain temps, car il y a un délai à respecter. En raison de ce délai, je ne veux pas que chaque donnée exécute la tâche successivement, je veux qu'elles soient toutes exécutées en parallèle. Devrais-je utiliser le multiprocessus ou le threading pour cette opération ?

J'ai essayé d'utiliser le threading mais j'ai eu quelques problèmes, souvent certaines tâches ne se déclenchaient jamais.

30voto

Christopher Points 5252

Si vous êtes vraiment limité par le calcul, l'utilisation de l'option module multiprocesseur est probablement la solution la plus légère (tant en termes de consommation de mémoire que de difficulté de mise en œuvre).

Si vous êtes lié aux E/S, l'utilisation de l'option module d'enfilage vous donnera généralement de bons résultats. Assurez-vous d'utiliser un stockage thread safe (comme la Queue) pour transmettre les données à vos threads. Ou bien remettez-leur un seul élément de données qui leur est propre lorsqu'ils sont créés.

PyPy est axé sur la performance. Il dispose d'un certain nombre de fonctionnalités qui peuvent aider au traitement lié au calcul. Il prend également en charge la mémoire transactionnelle logicielle, bien qu'elle ne soit pas encore de qualité industrielle. La promesse est que vous pouvez utiliser des mécanismes parallèles ou simultanés plus simples que le multiprocessing (qui a quelques exigences gênantes).

Python sans queue ni tête est également une bonne idée. Stackless a des problèmes de portabilité comme indiqué ci-dessus. Hirondelle libre était prometteur, mais il est aujourd'hui défunt. Pyston est une autre implémentation (inachevée) de Python axée sur la vitesse. Elle adopte une approche différente de celle de PyPy, ce qui peut donner lieu à des gains de vitesse meilleurs (ou simplement différents).

9voto

Davmuz Points 532

Les tâches sont exécutées de manière séquentielle mais vous avez l'illusion qu'elles sont exécutées en parallèle. Les tâches sont bonnes lorsque vous les utilisez pour des fichiers ou des entrées/sorties de connexion et parce qu'elles sont légères.

Le multiprocessus avec pool peut être la bonne solution pour vous, car les processus fonctionnent en parallèle et sont donc très utiles pour le calcul intensif, chaque processus étant exécuté sur un seul processeur (ou cœur).

La configuration du multiprocessus peut être très facile :

from multiprocessing import Pool

def worker(input_item):
    output = do_some_work()
    return output

pool = Pool() # it make one process for each CPU (or core) of your PC. Use "Pool(4)" to force to use 4 processes, for example.
list_of_results = pool.map(worker, input_list) # Launch all automatically

7voto

S.Lott Points 207588

Pour les petites collections de données, il suffit de créer des sous-processus avec sous-processus.Popen .

Chaque sous-processus peut simplement obtenir son morceau de données de stdin ou des arguments de la ligne de commande, faire son traitement, et simplement écrire le résultat dans un fichier de sortie.

Lorsque tous les sous-processus sont terminés (ou ont expiré), il suffit de fusionner les fichiers de sortie.

Très simple.

7voto

Mark Rushakoff Points 97350

Vous pourriez envisager d'examiner Python sans queue ni tête . Si vous avez le contrôle sur la fonction qui prend beaucoup de temps, vous pouvez simplement lancer des stackless.schedule() s à l'intérieur (disant yield à la prochaine coroutine), ou bien vous pouvez mettre Stackless en multitâche préemptif .

Dans Stackless, vous n'avez pas de fils, mais tasklets o verdures qui sont essentiellement des fils très légers. Cela fonctionne très bien dans le sens où il y a un cadre assez bon avec très peu de configuration pour faire fonctionner le multitâche.

Cependant, Stackless entrave la portabilité car vous devez remplacer quelques bibliothèques Python standard -- Stackless supprime la dépendance à la pile C. Il est très portable si l'utilisateur suivant a également Stackless installé, mais ce sera rarement le cas.

0voto

ire_and_curses Points 32802

L'utilisation du modèle de threading de CPython ne vous donnera aucune amélioration des performances, car les threads ne sont pas réellement exécutés en parallèle, en raison de la façon dont le garbage collection est géré. Le multiprocessus permettrait une exécution parallèle. Dans ce cas, il est évident que vous devez disposer de plusieurs cœurs pour y répartir vos tâches parallèles.

Il y a beaucoup plus d'informations disponibles dans cette question connexe .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X