Pourquoi Python a-t-il été écrit avec le GIL?

Le verrou dinterprétation global (GIL) semble être souvent cité comme une raison majeure pour laquelle le threading et autres est une touche délicate en Python – ce qui soulève la question « Pourquoi cela a-t-il été fait en premier lieu? »

Nétant pas un programmeur, je nai aucune idée de pourquoi cela pourrait être – quelle était la logique derrière la mise en place du GIL?

Commentaires

  • L article Wikipedia indique que  » le GIL peut être un obstacle important au parallélisme – un prix payé pour avoir le dynamisme du langage  » , et continue en disant que  » Les raisons demployer un tel verrou incluent: une vitesse accrue des programmes à un seul thread (pas besoin dacquérir ou de libérer les verrous sur toutes les structures de données séparément), et une intégration facile des bibliothèques C qui sont généralement pas thread-safe.  »
  • @RobertHarvey, le dynamisme na rien à voir avec ça. Le problème est la mutation.
  • stackoverflow.com/questions/265687/…
  • Peut ‘ t aider à penser que, comme le manque de ‘ de valeurs numériques non signées de Java, il était destiné à empêcher les personnes ‘ Je ne sais pas ce quils ‘ font se tirer une balle dans le pied. Malheureusement, quiconque sait sait ce qu’il fait ‘ obtient un langage déficient, ce qui est vraiment dommage car Python bascule de tant d’autres manières
  • @Basic il doit y avoir un moyen standard de gérer les tableaux doctets en Java (je nai ‘ que je ne lai pas utilisé depuis longtemps) afin de faire des calculs cryptographiques. Python (par exemple) na ‘ t avoir des nombres signés, mais je ne ‘ t même pas essayer de faire des opérations au niveau du bit car il y a de meilleures façons.

Réponse

Il existe plusieurs implémentations de Python, par exemple, CPython, IronPython, RPython, etc.

Certains dentre eux ont un GIL, dautres pas. Par exemple, CPython a le GIL:

From http://en.wikipedia.org/wiki/Global_Interpreter_Lock

Les applications écrites dans des langages de programmation avec un GIL peuvent être conçues pour utiliser des processus séparés pour atteindre un parallélisme complet, car chaque processus a son propre interpréteur et à son tour a son propre GIL.

Avantages du GIL

  • Augmentation de la vitesse des programmes à un seul thread.
  • Intégration facile des bibliothèques C qui ne sont généralement pas thread-safe.

Pourquoi Python (CPython et autres) utilise le GIL

En CPython, le verrou dinterprétation global, ou GIL, est un mutex qui empêche plusieurs threads natifs dexécuter des bytecodes Python à la fois. Ce verrou est nécessaire principalement parce que la gestion de la mémoire de CPython nest pas sûre pour les threads.

Le GIL est controversé car il empêche les programmes CPython multithread de tirer pleinement parti des systèmes multiprocesseurs dans certaines situations. Notez que le blocage ou les opérations de longue durée, telles que les E / S, le traitement dimage et le calcul des nombres NumPy, se produisent en dehors du GIL. Par conséquent, ce nest que dans les programmes multithread qui passent beaucoup de temps à lintérieur du GIL, interprétant le bytecode CPython, que le GIL devient un goulot détranglement.

Python a un GIL par opposition au verrouillage fin pour plusieurs raisons:

  • Cest plus rapide dans le cas monothread.

  • Cest plus rapide dans le cas du multi-thread pour les programmes liés aux entrées / sorties.

  • Cest plus rapide dans le cas du multi-thread pour les programmes liés au processeur qui font leur travail intensif en calcul dans les bibliothèques C.

  • Cela rend Extensions C plus faciles à écrire: il ny aura pas de changement de threads Python sauf là où vous lautorisez (i.e. entre les macros Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS).

  • Cela facilite lencapsulation des bibliothèques C. Vous navez pas à vous soucier de la sécurité des threads. Si la bibliothèque nest pas thread-safe, gardez simplement le GIL verrouillé pendant que vous lappelez.

Le GIL peut être libérée par les extensions C. La bibliothèque standard de Python libère le GIL autour de chaque appel dentrées / sorties de blocage. Ainsi, le GIL na aucune conséquence sur les performances des serveurs liés aux entrées / sorties. Vous pouvez ainsi créer des serveurs réseau en Python en utilisant des processus (fork), des threads ou des entrées / sorties asynchrones, et le GIL ne vous gênera pas.

Les bibliothèques numériques en C ou Fortran peuvent de la même manière être appelées avec le GIL libéré. Pendant que votre extension C attend la fin dune FFT, linterpréteur exécutera dautres threads Python.Un GIL est donc plus facile et plus rapide que le verrouillage à grain fin dans ce cas également. Cela constitue lessentiel du travail numérique. Lextension NumPy libère le GIL chaque fois que possible.

Les threads sont généralement une mauvaise façon décrire la plupart des programmes serveur. Si la charge est faible, la fourche est plus facile. Si la charge est élevée, les entrées / sorties asynchrones et la programmation événementielle (par exemple en utilisant le framework Twisted de Python) sont meilleures. La seule excuse pour utiliser des threads est le manque de os.fork sous Windows.

Le GIL est un problème si, et seulement si, vous faites un travail intensif en CPU en Python pur. Ici, vous pouvez obtenir une conception plus propre en utilisant des processus et la transmission de messages (par exemple mpi4py). Il existe également un module de « traitement » dans le fromage Python shop, qui donne aux processus la même interface que les threads (cest-à-dire remplace threading.Thread par processing.Process).

Les threads peuvent être utilisés pour maintenir la réactivité dune interface graphique quel que soit le GIL. Si le GIL altère vos performances (cf. la discussion ci-dessus), vous pouvez laisser votre fil générer un processus et attendre quil se termine.

Commentaires

  • On dirait des raisins aigres pour moi. Python peut ‘ t faire des threads correctement, donc vous inventez les raisons pour lesquelles les threads sont inutiles ou même mauvais.  » Si la charge est faible, fo rking est plus facile « , sérieusement? Et le GIL est  » plus rapide  » pour tous ces cas uniquement si vous insistez pour utiliser le GC de comptage de références.
  • s/RPython/PyPy/g. @MichaelBorgwardt Donner des raisons pro GIL est un peu le point de la question, nest-ce pas ‘? Bien que je convienne que certains des contenus de cette réponse (à savoir la discussion des alternatives) sont hors de propos. Et pour le meilleur ou pour le pire, il est désormais presque impossible de se débarrasser du refcounting – il est profondément ancré dans toute lAPI et la base de code; il ‘ est presque impossible de sen débarrasser sans réécrire la moitié du code et casser tout le code externe.
  • Don ‘ t oublier la bibliothèque multiprocessing – standard depuis 2.6. Les pools de travail de ‘ sont une abstraction super astucieuse pour certains types simples de parallélisme.
  • @alcalde Uniquement si vous ne le faites pas ‘ je ne sais pas ce que vous ‘ faites et / ou vous ne ‘ ne voulez pas que vos threads puissent fonctionner en coopération / communiquer. Sinon, cest ‘ une douleur royale à larrière, surtout compte tenu de la surcharge de lancement dun nouveau processus sur certains OS. Nous avons des serveurs avec 32 cœurs, donc pour les utiliser pleinement en CPython, jai besoin de 32 processus ‘. Cette ‘ nest pas une  » bonne solution  » elle ‘ est un hack pour contourner les insuffisances de CPython ‘.
  • Le fait que les threads existent sur des plates-formes autres que Windows devrait être une preuve suffisante que forking isn ‘ t adéquat dans toutes les situations.

Réponse

Dabord off: Python na pas de GIL. Python est un langage de programmation. Un langage de programmation est un ensemble de règles et de restrictions mathématiques abstraites. Il ny a rien dans la spécification du langage Python qui dit quil doit y avoir un GIL.

Il existe de nombreuses implémentations différentes de Python. Certaines ont un GIL, dautres pas.

Une explication simple pour avoir un GIL est que lécriture de code simultané est difficile. En plaçant un verrou géant autour de votre code, vous le forcez à toujours sexécuter en série. Problème résolu!

En CPython, en particulier, un objectif important est de faciliter lextension de linterpréteur avec des plugins écrits en C. Encore une fois, lécriture de code simultané est difficile, donc en garantissant quil ny aura pas concurrence, cela facilite lécriture dextensions pour linterpréteur. De plus, beaucoup de ces extensions ne sont que de minces enveloppes autour des bibliothèques existantes qui nont peut-être pas été écrites avec la concurrence à lesprit.

Commentaires

  • Que ‘ est le même argument que Java ‘ manque de types numériques non signés – les développeurs pensent que tout le monde est plus idiot queux …
  • @Basic – croyez-le ou non, même lorsque vous ‘ nêtes pas vraiment, vraiment stupide, il savère quavoir un langage qui fait des hypothèses simplificatrices qui signifient que vous ne ‘ T penser à certaines choses pour les faire fonctionner est toujours une chose utile.CPython est idéal pour certaines choses, y compris les applications multithread simples (où le programme est lié aux E / S, ce que beaucoup sont, et donc le GIL na pas ‘ t important), car les décisions de conception qui ont pris le GIL la meilleure solution facilite également la programmation de ces applications, en particulier le fait quil supporte les opérations atomiques sur les collections .
  • @Jules Oui, il ‘ est très pratique jusquà ce que vous ayez besoin de ces capacités. cpython ‘ s  » préféré  » solution de  » écrivez-le simplement dans un autre langage comme c ++ « , ce qui signifie que vous perdez chaque avantage de python individuellement. Si vous ‘ réécrivez la moitié de votre code en C ++, alors pourquoi partir de Python? Bien sûr, pour les petits projets API / glue, ‘ est rapide et facile, et pour ETL, il est ‘ sans égal, mais ‘ ne convient pas à tout ce qui nécessite de lourdes charges. Identique à lutilisation de Java pour parler au matériel … Il ‘ est presque comique les cerceaux que vous devez franchir.
  • @Basic One of Python ‘ et donc dans une extension CPython ‘ la philosophie de base est de rendre la technologie  » conviviale et facile à utiliser « . La programmation parallèle sans verrouillage global nest pas ça. Étant donné quil existe de nombreuses implémentations sans GIL, il est logique den fournir au moins une.
  • Vous dites  » quil est logique de fournir au moins une une implémentation qui la.  » comme ça ‘ est la conclusion évidente, mais pas dautre langage I ‘ suis conscient dentraver ses développeurs de cette manière, donc il peut ‘ être cela évident.

Réponse

À quoi sert un GIL?

La documentation CAPI a ceci à dire sur le sujet:

Linterpréteur Python nest pas entièrement thread-safe . Afin de prendre en charge les programmes Python multithreads, il existe un verrou global, appelé verrou dinterpréteur global ou GIL, qui doit être conservé par le thread actuel avant de pouvoir accéder en toute sécurité aux objets Python. Sans le verrou, même les opérations les plus simples pourraient causer des problèmes dans un programme multi-thread: par exemple, lorsque deux threads incrémentent simultanément le nombre de références du même objet, le nombre de références pourrait finir par être incrémenté une seule fois au lieu de deux.

En dautres termes, le GIL empêche la corruption détat. Les programmes Python ne devraient jamais produire une erreur de segmentation, car seules les opérations de sauvegarde de la mémoire sont autorisées. Le GIL étend cette assurance aux programmes multithreads.

Quelles sont les alternatives?

Si le but du GIL est de protéger létat contre la corruption, alors une alternative évidente est le verrouillage à un grain beaucoup plus fin; peut-être au niveau par objet. Le problème avec ceci est que bien quil ait été démontré quil augmente les performances des programmes multi-threads, il a plus de surcharge et les programmes à thread unique en souffrent.

Commentaires

  • Ce serait génial de laisser un utilisateur exécuter un programme avec une option dinterprétation remplaçant le gil pour un verrou à grain fin, et savoir dune manière ou dune autre – en lecture seule – si le processus actuel a été déclenché avec ou sans gil.
  • Malgré GIL, jai réussi à produire une erreur de segmentation dans un programme multithread en raison dune utilisation imprudente du module pyodbc. Ainsi  » ne devrait jamais produire un défaut de segmentation  » est une erreur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *