python, le GIL, pourquoi et tout ça ?
Par ppr le lundi 17 septembre 2007, 18:15 - geeking - Lien permanent
Avec eau (aka. Le Frelon Dardé du Gabon) on discutait d'une appli en développement basée sur python et la pylibpcap. Le modèle de l'application était composé de deux threads : une thread pour l'envoi de paquets et une thread utilisant pcap pour la réception. Le problème de ce modèle appliqué à python est que cette application ne pouvait pas marcher "as is" : la thread d'envoi ne pouvait pas démarrer car la pylibpcap acquiert le GIL (Global Interpreter Lock) et ne le libère jamais. En d'autres termes : la thread d'envoi n'était jamais démarré et python se consacrait à la thread de réception qui, du coup, ne recevait rien.
Petite explication nécessaire : les développeurs de Python ont décidé de développer un interpréteur qui n'est pas thread-safe, pour la simplicité. Cependant, pour tout de même proposer des threads, il leur a été nécessaire de créer un lock, global, entre elles. Chaque thread acquiert donc ce lock (le GIL) exécute un nombre donné (et configurable) d'instructions python, puis libère le GIL. De l'extérieur tout se passe comme si les threads étaient exécutées séquentiellement pendant un certain nombre d'instructions plutôt que parallèlement. C'est la raison d'un des plus gros trolls sur python, après l'indentation : le GIL.
La réponse de Guido van Rossum, le BDFL de python est toujours la même : n'utilisez pas de threads, développez plusieurs processus et faites les communiquer par IPC. C'est un des éléments de la philosophie python et les arguments de Guido sont nombreux.
Donc, en ce qui concerne l'application en développement, plutôt que de patcher la pylibpcap, il est peut-être plus intéressant de développer l'application dans un modèle "à la python" avec un processus d'écoute qui transmet à un processus de traitement les paquets lus, par IPC.
L'intérêt n'est pas de décider si le GIL est une bonne ou une mauvaise idée mais de comprendre pourquoi il est là et la philosophie du langage quand on a à l'utiliser. Donc, voici les quelques ressources citées dans l'article, pour ceux qui veulent en savoir plus :
- Python/C API Reference Manual, Thread State and the Global Interpreter Lock, http://docs.python.org/api/threads.html
- python-list, pylibpcap and multiple threads : http://mail.python.org/pipermail/python-list/2005-January/303798.html
- Needled by Threads : http://cleverdevil.org/computing/30/needled-by-threads
- python-3000, the future of the GIL : http://mail.python.org/pipermail/python-3000/2007-May/007414.html

Commentaires
L'enfer du GIL! De plus si il vous arrive de coder du module python en C pour ajouter des trucs pas faisables autrement, il vous faut compter avec le GIL si jamais l'appli finale utilise des threads. Dans ce cas il faut rendre votre module thread safe en entourant certains calls genre read().. avec:
Py_BEGIN_ALLOW_THREADS
read()
Py_END_ALLOW_THREADS
Et quoi qu'on en dise sans thread la vie serait moins marrante,
meme si Guido van Rossum vous dit le contraire. Petite pensee a l'aprem que j'ai perdu en cherchant a comprendre pourquoi mon truc bloquait.
Excellent post. It makes me realize the energy of words and pictures. I learn a lot, thank you! Wish you make a further progress in the future.