962 votes

Multiprocessing vs Threading Python

J'essaie de comprendre les avantages de multitraitement sur filetage . Je sais que multitraitement permet de contourner le verrou de l'interprète global, mais quels sont les autres avantages, et peut-on filetage ne pas faire la même chose ?

7 votes

Je pense que cela peut être utile en général : blogs.datalogics.com/2013/09/25/ Bien qu'il puisse y avoir des choses intéressantes selon la langue. Par exemple, selon le lien d'Andrew Sledge, les threads python sont plus lents. En java, c'est tout le contraire, les processus java sont beaucoup plus lents que les threads, car il faut un nouveau jvm pour démarrer un nouveau processus.

5 votes

Aucune des deux premières réponses( sommet actuel , deuxième réponse )couvre les DGE de manière significative. Voici une réponse qui couvre l'aspect DGE : stackoverflow.com/a/18114882/52074

0 votes

@AndrasDeak pouvons-nous fermer dans l'autre sens comme prévu : meta.stackoverflow.com/questions/251938/ puisqu'il a beaucoup plus de votes positifs/réponses ?

933voto

Jeremy Brown Points 4950

Voici quelques avantages et inconvénients que j'ai trouvés.

Multiprocessing

Pour

  • Espace mémoire séparé
  • Le code est généralement simple
  • Exploitation de plusieurs processeurs et cœurs.
  • Evite les limitations de GIL pour cPython
  • Élimine la plupart des besoins en primitives de synchronisation, sauf si vous utilisez la mémoire partagée (il s'agit plutôt d'un modèle de communication pour IPC).
  • Les processus enfants peuvent être interrompus/supprimés
  • Python multiprocessing comprend des abstractions utiles avec une interface semblable à celle du module threading.Thread
  • Un must avec cPython pour les traitements liés au CPU

Cons

  • IPC un peu plus compliqué avec plus de surcharge (modèle de communication vs. mémoire partagée/objets)
  • Empreinte mémoire plus importante

Enfilage

Pour

  • Léger - faible empreinte mémoire
  • Mémoire partagée - facilite l'accès à l'état depuis un autre contexte.
  • Vous pouvez facilement créer des interfaces utilisateur réactives.
  • Les modules d'extension C de cPython qui libèrent correctement le GIL fonctionneront en parallèle.
  • Excellente option pour les applications liées aux E/S

Cons

  • cPython - soumis à la GIL
  • Ne peut être interrompu ou tué
  • Si vous ne suivez pas un modèle de file d'attente de commandes/pompe à messages (en utilisant l'option Queue ), alors l'utilisation manuelle des primitives de synchronisation devient une nécessité (des décisions sont nécessaires pour la granularité du verrouillage).
  • Le code est généralement plus difficile à comprendre et à mettre en œuvre - le risque de conditions de course augmente considérablement.

1 votes

Il pourrait être possible pour le multitraitement de réduire l'empreinte mémoire dans le cas des listes libres.

52 votes

Pour le multiprocessus : "Tire parti de plusieurs processeurs et cœurs". Le threading a-t-il aussi cet avantage ?

108 votes

@Deqing non, ce n'est pas le cas. En Python, à cause du GIL (Global Interpreter Lock), un seul processus Python ne peut pas exécuter des threads en parallèle (utiliser plusieurs cœurs). Il peut cependant les exécuter simultanément (changement de contexte pendant les opérations liées aux E/S).

855voto

Sjoerd Points 34671

Le site threading utilise des threads, le module multiprocessing utilise des processus. La différence est que les threads s'exécutent dans le même espace mémoire, alors que les processus ont une mémoire séparée. Cela rend un peu plus difficile le partage d'objets entre processus en cas de multiprocessing. Comme les threads utilisent la même mémoire, des précautions doivent être prises pour éviter que deux threads n'écrivent dans la même mémoire en même temps. C'est à cela que sert le verrou global de l'interpréteur.

La création de processus est un peu plus lente que la création de fils.

213 votes

Le GIL dans cPython n'est pas protéger l'état de votre programme. Il protège l'état de l'interpréteur.

49 votes

De plus, le système d'exploitation gère l'ordonnancement des processus. La bibliothèque threading gère l'ordonnancement des threads. Et les threads partagent l'ordonnancement des E/S - ce qui peut constituer un goulot d'étranglement. Les processus ont un ordonnancement E/S indépendant.

3 votes

Qu'en est-il des performances IPC du multiprocesseur ? Pour un programme qui nécessite un partage fréquent d'objets entre les processus (par exemple, par l'intermédiaire de la file d'attente multiprocessing.Queue), quelles sont les performances comparées à celles de la file d'attente in-process ?

252voto

Simon Hibbs Points 1827

Le rôle du threading est de permettre aux applications d'être réactives. Supposons que vous ayez une connexion à une base de données et que vous deviez répondre aux entrées de l'utilisateur. Sans threading, si la connexion à la base de données est occupée, l'application ne sera pas en mesure de répondre à l'utilisateur. En séparant la connexion à la base de données dans un thread distinct, vous pouvez rendre l'application plus réactive. De plus, comme les deux threads se trouvent dans le même processus, ils peuvent accéder aux mêmes structures de données - de bonnes performances et une conception logicielle flexible.

Notez qu'en raison de la GIL, l'application ne fait pas réellement deux choses à la fois, mais ce que nous avons fait, c'est placer le verrou de ressources sur la base de données dans un thread séparé afin que le temps CPU puisse être basculé entre lui et l'interaction avec l'utilisateur. Le temps CPU est rationné entre les threads.

Le multitraitement est destiné aux cas où vous souhaitez vraiment que plusieurs tâches soient effectuées à la fois. Supposons que votre application doive se connecter à 6 bases de données et effectuer une transformation matricielle complexe sur chaque ensemble de données. Le fait de placer chaque tâche dans un thread séparé pourrait aider un peu car lorsqu'une connexion est inactive, une autre pourrait obtenir du temps CPU, mais le traitement ne serait pas effectué en parallèle car la GIL signifie que vous n'utilisez jamais que les ressources d'un seul CPU. En plaçant chaque tâche dans un processus multiprocesseur, chacune d'entre elles peut être exécutée sur sa propre unité centrale et fonctionner à pleine efficacité.

1 votes

"mais le traitement ne serait pas effectué en parallèle parce que la GIL signifie que vous n'utilisez jamais que les ressources d'un seul CPU" GIL en multiprocessing comment se fait-il que .... ?

6 votes

@NishantKashyap - Relisez la phrase dont vous avez tiré cette citation. Simon parle du traitement de plusieurs threads - il ne s'agit pas de multiprocessing.

0 votes

En ce qui concerne les différences de mémoire, il s'agit d'un coût initial de type capEx. OpEx (running), les threads peuvent être aussi gourmands que les processus. Vous avez le contrôle des deux. Traitez-les comme des coûts.

48voto

Marcelo Cantos Points 91211

Le principal avantage est l'isolement. Un processus qui s'effondre n'entraînera pas l'effondrement d'autres processus, alors qu'un thread qui s'effondre fera probablement des ravages dans les autres threads.

5 votes

Je suis presque sûr que c'est faux. Si un thread standard en Python se termine en levant une exception, rien ne se passera lorsque vous le rejoindrez. J'ai écrit ma propre sous-classe de thread qui attrape l'exception dans un thread et la lève à nouveau sur le thread qui le rejoint, parce que le fait qu'il soit simplement ignoré était vraiment mauvais (conduisant à d'autres bugs difficiles à trouver.) Un processus aurait le même comportement. À moins que par plantage, vous ne vouliez dire le plantage réel de Python, et non la levée d'une exception. Si vous constatez un jour que Python se plante, c'est un bogue que vous devez signaler. Python devrait toujours lever des exceptions et ne jamais planter.

9 votes

Les threads peuvent faire bien plus que lever une exception. Un thread dévoyé peut, via un code natif ou ctypique bogué, détruire des structures de mémoire n'importe où dans le processus, y compris le runtime python lui-même, corrompant ainsi l'ensemble du processus.

0 votes

@jar d'un point de vue générique, la réponse de Marcelo est plus complète. Si le système est vraiment critique, vous ne devriez jamais vous fier au fait que "les choses fonctionnent comme prévu". Avec des espaces mémoire séparés, un débordement doit se produire afin d'endommager les processus voisins, ce qui est une chose plus improbable que la situation exposée par Marcelo.

29voto

chrissygormley Points 3568

Un autre élément non mentionné est que la vitesse dépend du système d'exploitation que vous utilisez. Dans Windows, les processus sont coûteux et les threads sont donc préférables dans Windows, mais dans unix, les processus sont plus rapides que leurs variantes Windows et l'utilisation de processus dans unix est plus sûre et plus rapide.

7 votes

Avez-vous des chiffres réels pour étayer cette affirmation ? Par exemple, en comparant l'exécution d'une tâche en série, puis sur plusieurs threads, puis sur plusieurs processus, sous Windows et Unix ?

3 votes

D'accord avec la question de @ArtOfWarfare. Des chiffres ? Recommandez-vous d'utiliser Threads pour Windows ?

0 votes

Le système d'exploitation n'a pas beaucoup d'importance car la GIL de Python ne lui permet pas d'exécuter plusieurs threads sur un seul processus. Le multiprocessing sera plus rapide sous Windows et Linux.

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