Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Threading et performance

8 réponses
Avatar
Christope Dutrieux
Bonjour à tous,

J'ai un problème étrange de performance avec le module threading.

J'ai construit une application Python2.3/GTK/PYGTK2.4/MySQL4 qui fait appel au
module threading pour les opérations longues de manipulation de données.

En gros, le thread principal de l'appli construit et gère l'interface
graphique. Il lance un thread secondaire qui manipule les données. Les 2
thread se partagent une liste python afin de permettre au thread
principal de rendre compte de l'avancement du calcul dans le thread
secondaire. Bref, du classique.

Cette application fonctionne parfaitement. Lorsque je suis en mode
debugging, les performances sont très honorables et le calcul se fait en
quelques minutes. Par contre, dès que je lance l'application hors debug,
les performances de mon thread secondaire sont excecrables et il me faut
pas loin de 30 minutes pour terminer le traitement.

Je précise que :

- je fonctionne sous windows XP.
- mon thread est secondaire est en mode daemon
- J'ai eu beau regarder la doc, je n'y ai pas trouvé d'option de
priorité dans le module threading

Auriez vous une petite idée de la cause d'un tel comportement ?

Par avance merci

Christophe

8 réponses

Avatar
Jean-François Piéronne
Salut,

Bonjour à tous,

J'ai un problème étrange de performance avec le module threading.

J'ai construit une application Python2.3/GTK/PYGTK2.4/MySQL4 qui fait appel au
module threading pour les opérations longues de manipulation de données.



Si tu pense que le problème vient de Python, il y a eu, il y a peux de
temps, toute une discussion la dessus dans la mailing list des
developpeurs, tu peux consulter les archive a partir de:
http://mail.python.org/pipermail/python-dev/

En particulier septempbre et octobre 2005, regarde par exemple
Pythonic concurrency - cooperative MT
Sandboxed Threads in Python
Variant of removing GIL


[snip]


Par avance merci

Christophe





Jean-François

Avatar
Amaury
Bonjour à tous,

J'ai un problème étrange de performance avec le module threading.

J'ai construit une application Python2.3/GTK/PYGTK2.4/MySQL4 qui fait appel au
module threading pour les opérations longues de manipulation de données.

En gros, le thread principal de l'appli construit et gère l'interface
graphique. Il lance un thread secondaire qui manipule les données. Les 2
thread se partagent une liste python afin de permettre au thread
principal de rendre compte de l'avancement du calcul dans le thread
secondaire. Bref, du classique.

Cette application fonctionne parfaitement. Lorsque je suis en mode
debugging, les performances sont très honorables et le calcul se fait en
quelques minutes. Par contre, dès que je lance l'application hors debug,
les performances de mon thread secondaire sont excecrables et il me faut
pas loin de 30 minutes pour terminer le traitement.

Je précise que :

- je fonctionne sous windows XP.
- mon thread est secondaire est en mode daemon
- J'ai eu beau regarder la doc, je n'y ai pas trouvé d'option de
priorité dans le module threading

Auriez vous une petite idée de la cause d'un tel comportement ?

Par avance merci

Christophe





C'est certainement la faute à GIL : le fameux 'Global Interpreter Lock'
qui fait qu'un seul thread à la fois peut exécuter du python.
Normalement, dès qu'il y a un appel système (lecture de fichier, base de
données, interface graphique), le GIL est lâché temporairement pour
donner une chance aux autres threads de prendre la main.
Mais pyGTK qui réalise l'interface entre python et GTK ne le fait pas,
donc les autres threads n'ont presque jamais la main...

En cherchant dans google "pygtk release GIL", j'ai trouvé ceci:
http://pygtk.org/pygtk2reference/gdk-functions.html
gtk.gdk.threads_init() est sans doute la fonction qui t'aidera.

--
Amaury

Avatar
Christope Dutrieux
Le Tue, 18 Oct 2005 08:37:03 +0200, Amaury a écrit :


C'est certainement la faute à GIL : le fameux 'Global Interpreter Lock'
qui fait qu'un seul thread à la fois peut exécuter du python.
Normalement, dès qu'il y a un appel système (lecture de fichier, base de
données, interface graphique), le GIL est lâché temporairement pour
donner une chance aux autres threads de prendre la main.
Mais pyGTK qui réalise l'interface entre python et GTK ne le fait pas,
donc les autres threads n'ont presque jamais la main...

En cherchant dans google "pygtk release GIL", j'ai trouvé ceci:
http://pygtk.org/pygtk2reference/gdk-functions.html
gtk.gdk.threads_init() est sans doute la fonction qui t'aidera.


C'est assez probable effectivement. J'avais déjà inséré un
gtk.gdk.threads_init() juste avant l'appel du gtk.main() comme indiqué
dans la documentation mais si cela ne semble pas poser de soucis
lorsque je fais tourner l'appli sur plate forme linux, cela a pour effet
de 'geler' le fonctionnement de l'interface graphique dès que je suis
sous XP - le contrôles ne s'affichent que partiellement :-(

a noter néanmoins que le second thread ne fait pas du tout appel à GTK
donc à priori pas besoin d'appel à gtk.gdk.thread_enter() ni
gtk.gdk.thread_leave()

Il est vrai que j'utilise la version 2.3 de Python ainsi qu'une version
2.4 de PyGTK. Je vais essayer avec des versions récentes.

Merci pour m'avoir répondu. si j'ai du neuf, je posterai le résultat de
mes investigations.

Christophe

Avatar
Olivier Ravard
"Christope Dutrieux" a écrit dans le message
de news:


C'est certainement la faute à GIL : le fameux 'Global Interpreter Lock'
qui fait qu'un seul thread à la fois peut exécuter du python.
Normalement, dès qu'il y a un appel système (lecture de fichier, base de
données, interface graphique), le GIL est lâché temporairement pour
donner une chance aux autres threads de prendre la main.
Mais pyGTK qui réalise l'interface entre python et GTK ne le fait pas,
donc les autres threads n'ont presque jamais la main...

En cherchant dans google "pygtk release GIL", j'ai trouvé ceci:
http://pygtk.org/pygtk2reference/gdk-functions.html
gtk.gdk.threads_init() est sans doute la fonction qui t'aidera.


C'est assez probable effectivement. J'avais déjà inséré un
gtk.gdk.threads_init() juste avant l'appel du gtk.main() comme indiqué
dans la documentation mais si cela ne semble pas poser de soucis
lorsque je fais tourner l'appli sur plate forme linux, cela a pour effet
de 'geler' le fonctionnement de l'interface graphique dès que je suis
sous XP - le contrôles ne s'affichent que partiellement :-(

a noter néanmoins que le second thread ne fait pas du tout appel à GTK
donc à priori pas besoin d'appel à gtk.gdk.thread_enter() ni
gtk.gdk.thread_leave()

Il est vrai que j'utilise la version 2.3 de Python ainsi qu'une version
2.4 de PyGTK. Je vais essayer avec des versions récentes.

Merci pour m'avoir répondu. si j'ai du neuf, je posterai le résultat de
mes investigations.



Je n'apporte pas de solution, mais juste pour dire que j'ai le même genre de
problèmes avec les threads
avec Python 2.3 et WxPython. Tout se passe bien sous Linux mais sous XP
l'interface
est "gelée" lorsque des threads prennent ne serait-ce qu'un peu de
ressources...

Christophe



Avatar
Amaury
Bonjour,

Je n'apporte pas de solution, mais juste pour dire que j'ai le même genre de
problèmes avec les threads
avec Python 2.3 et WxPython. Tout se passe bien sous Linux mais sous XP
l'interface
est "gelée" lorsque des threads prennent ne serait-ce qu'un peu de
ressources...


Que font ces threads ? En particulier, s'ils appellent des fonctions
externes, prennent-ils le soin de "relâcher" le GIL ? Ou bien sont-ils
écrits en "pur" Python ?

--
Amaury

Avatar
O.R.
"Amaury" a écrit dans le message de news:
435d1254$0$41149$
Bonjour,

Je n'apporte pas de solution, mais juste pour dire que j'ai le même genre
de problèmes avec les threads
avec Python 2.3 et WxPython. Tout se passe bien sous Linux mais sous XP
l'interface
est "gelée" lorsque des threads prennent ne serait-ce qu'un peu de
ressources...


Que font ces threads ? En particulier, s'ils appellent des fonctions
externes, prennent-ils le soin de "relâcher" le GIL ? Ou bien sont-ils
écrits en "pur" Python ?



Il sont écrits en pure python et font appel à des modules C++. A part ça,
ils
ne relâchent rien du tout.

--
Amaury



Avatar
Amaury
"Amaury" a écrit dans le message de news:
435d1254$0$41149$

Bonjour,


Que font ces threads ? En particulier, s'ils appellent des fonctions
externes, prennent-ils le soin de "relâcher" le GIL ? Ou bien sont-ils
écrits en "pur" Python ?




Il sont écrits en pure python et font appel à des modules C++. A part ça,
ils
ne relâchent rien du tout.


Le "pur python" ne pose pas de problème : toutes les 100 instructions,
l'interpréteur Python relâche le GIL pour laisser une chance aux autres
threads.
Mais si le thread passe son temps dans les modules C++, il serait bon
d'encadrer les appels de fonctions qui prennent du temps entre les 2
macros qui sont faites pour cela :
Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS
Ce qui libère le thread qui gère l'affichage en wxPython.

--
Amaury


Avatar
O.R.
"Amaury" a écrit dans le message de news:
435e7d62$0$41144$
"Amaury" a écrit dans le message de news:
435d1254$0$41149$

Bonjour,


Que font ces threads ? En particulier, s'ils appellent des fonctions
externes, prennent-ils le soin de "relâcher" le GIL ? Ou bien sont-ils
écrits en "pur" Python ?




Il sont écrits en pure python et font appel à des modules C++. A part
ça, ils
ne relâchent rien du tout.


Le "pur python" ne pose pas de problème : toutes les 100 instructions,
l'interpréteur Python relâche le GIL pour laisser une chance aux autres
threads.
Mais si le thread passe son temps dans les modules C++, il serait bon
d'encadrer les appels de fonctions qui prennent du temps entre les 2
macros qui sont faites pour cela :
Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS
Ce qui libère le thread qui gère l'affichage en wxPython.



Merci. Je vais essayer de suite...

O.R.

--
Amaury