Après de nombreux débats, le comité de pilotage du langage Python a l'intention d'approuver une proposition, PEP 703, « Making the Global Interpreter Lock Optional in CPython » (rendre le verrouillage de l'interpréteur global optionnel dans CPython). Cette proposition est l'aboutissement de nombreuses tentatives au fil des ans pour supprimer le verrouillage global de l'interpréteur Global Interpter Lock (GIL) de Python. Sa suppression élimine un obstacle majeur au multithreading, améliorant de manière significative ses performances pour les charges de travail parallélisées. Avec cette proposition, la prise en charge de premier ordre du multithreading et de la concurrence dans Python est sur le point de devenir une réalité.
Un goulet d'étranglement nommé GIL
Le système de gestion de la mémoire de Python suit l'utilisation des objets en comptabilisant le nombre de références à chaque objet. Lorsque le nombre de références d'un objet tombe à zéro, l'objet est destiné à être supprimé. Comme Python a été créé à une époque où les systèmes multiprocesseurs étaient rares et où les processeurs multicœurs n'existaient pas, ce mécanisme de comptage des références n'est pas sûr pour les threads. Au lieu de cela, Python assure la sécurité des threads en n'autorisant qu'un seul thread à accéder à un objet à la fois. C'est la raison d'être de GIL.
Au fil des ans, de nombreux projets ont tenté de supprimer GIL. Ils ont permis aux programmes multithreads de s'exécuter plus rapidement, mais au prix d'une dégradation des performances des programmes monothreads. Étant donné que la grande majorité des applications Python sont monotâches, il s'agissait d'un mauvais compromis. Bien que les perfectionnements apportés à GIL aient permis d'améliorer sa gestion des applications multithread, elle reste un goulot d'étranglement important. Les développeurs de Python ont finalement décidé de supprimer GIL de CPython, mais seulement si cela pouvait se faire sans ralentir les programmes monotâches.
Comment fonctionnera Python sans GIL
Les propositions actuelles pour une édition de Python sans GIL utilisent un mélange de techniques pour rendre le comptage de références sûr pour les threads, et laisser la vitesse des programmes à un seul thread inchangée ou n'avoir qu'un impact minime. Il y a d’abord le comptage de référence biaisé. Le comptage des objets accédés par un seul thread est traité différemment (et plus rapidement) que le comptage des objets accédés par plusieurs threads. Étant donné que la plupart des objets ne sont accédés que par un seul thread, l'impact sur les programmes à un seul thread est minimisé. L’immortalisation, quant à elle, se base sur le fait que certains objets, comme None, n'ont jamais besoin d'être désalloués, de sorte que leur nombre de références n'a pas besoin d'être suivi.
Une autre technique, l’allocation de mémoire à l'épreuve des threads, est un nouveau système d'allocation de mémoire pour les objets CPython qui facilitera le suivi des objets dans ce que l’on appelle le garbage collector, et l'allocation de mémoire de manière sûre pour les threads. Enfin, une autre technique, appelée comptage de références différé, propose que le comptage des références de certains objets, comme les fonctions de haut niveau d'un module, soit différé en toute sécurité. Cela permet de gagner du temps et d'économiser des ressources.
Une adoption sur plusieurs années
La mise en œuvre de la PEP 703 est un projet à long terme qui se déroulera en plusieurs étapes sur plusieurs années. Pendant cette période, l'interpréteur CPython va évoluer pour rendre la version sans GIL d'abord optionnelle, puis supportée, et enfin la version standard de CPython. Pour ce faire, les développeurs de CPython ajouteront un mode de compilation expérimental « no-GIL » à CPython, de sorte que l'on puisse compiler une version de CPython avec ou sans la GIL. Finalement, le mode de compilation « no-GIL » deviendra le mode par défaut. Voici comment se déroule le projet de suppression de la GIL dans CPython. Les premières incarnations d'un CPython sans GIL seront expérimentales, à la fois pour les développeurs de CPython et pour la communauté Python dans son ensemble. Cette phase a plusieurs objectifs. Tout d’abord, impliquer le reste de la communauté Python. Tout changement majeur apporté à Python nécessite l'adhésion de l'ensemble de la communauté Python. Les versions expérimentales permettent aux utilisateurs de Python de tester leur code en toute sécurité et de voir comment se comporteront les codes threadés et non threadés.
Il s’agit également de donner aux distributions Python la possibilité, et non l'obligation, de livrer un Python sans GIL. Les distributions Python telles que Conda ou WinPython doivent garantir la compatibilité avec CPython. Pendant la phase de transition, elles pourraient offrir la possibilité d'installer la version normale ou sans GIL de CPython. Cela permettrait aux utilisateurs de Conda ou de WinPython de choisir la version la plus compatible avec leurs besoins. Enfin, lors de cette phase expérimentale, il s’agit de déterminer si le projet no-GIL vaut la peine. Si la communauté essaie les versions sans GIL à grande échelle et n'est pas satisfaite des résultats, les développeurs de CPython se réservent le droit de faire marche arrière. Le fait d'avoir deux versions signifie une charge de maintenance plus lourde à court terme, mais offre une porte de sortie si le projet no-GIL s'avère indigne.
Fixer une date butoir pour faire de no-GIL la version par défaut
La deuxième étape consistera à proposer la version no-GIL comme version alternative supportée pour CPython. Un utilisateur aura le choix d'installer soit la version no-GIL, soit la version GIL, l'une ou l'autre étant une version officiellement supportée de CPython qui reçoit des corrections de bogues, des correctifs de sécurité et des mises à jour. L'un des principaux objectifs de cette étape est de fixer une date butoir pour faire de no-GIL la valeur par défaut. Cela se produira probablement selon le même calendrier que la dépréciation et la suppression d'autres fonctionnalités de Python - au moins deux ou trois versions, ce qui signifie au moins deux ou trois ans.
L'étape finale consisterait à faire de la version sans GIL de CPython la version par défaut et à supprimer tout le code lié à la GIL de CPython. « Nous ne voulons pas attendre trop longtemps », écrit Thomas Wouters, développeur principal de CPython, « parce qu'avoir deux modes de construction communs peut être un lourd fardeau pour la communauté (car, par exemple, cela peut doubler les ressources de test et les scénarios de débogage), mais nous ne pouvons pas non plus nous précipiter. Nous pensons qu'il faudra jusqu'à cinq ans pour arriver à ce stade ».
Les plus grands défis de la suppression de la GIL
Les plus grands défis de ce plan ne sont pas seulement d'ordre technique, bien qu'ils soient considérables. Ce qui est encore plus important, c'est de savoir comment aligner le reste de l'écosystème Python sur ces changements et de s'assurer qu'un Python sans GIL ne crée pas plus de problèmes qu'il n'en résout. Selon Thomas Wouters, « tout changement dans le code tiers nécessaire pour s'adapter aux versions sans GIL devrait fonctionner dans les versions avec GIL (bien que la compatibilité ascendante avec les anciennes versions de Python doive toujours être prise en compte) ».
L'autre grand défi, comme mentionné ci-dessus, est « d'amener le reste de la communauté Python », poursuit-il, « ... et de s'assurer que les changements que nous voulons faire, et les changements que nous voulons qu'ils fassent, sont acceptables. Avant de nous engager à passer entièrement à la version sans GIL, nous devons obtenir le soutien de la communauté », ajoute ce développeur. « Nous ne pouvons pas simplement changer la valeur par défaut et attendre de la communauté qu'elle comprenne le travail qu'elle doit faire pour la supporter ». La communauté Python a connu d'énormes difficultés de croissance lors de la transition de Python 2 à Python 3, de sorte que tout changement important, comme la suppression de la GIL, devrait être parfaitement rétrocompatible. Comme l’affirme Thomas Wouters, « nous ne voulons pas d'une autre situation Python 3 ».