tkinter runs a busy-wait loop on interactive Python
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug report
Bug description:
In EventHook in Modules/_tkinter.c, we used to have the following block to run the event loop:
#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Py_BEGIN_ALLOW_THREADS
if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = event_tstate;
result = Tcl_DoOneEvent(TCL_DONT_WAIT);
tcl_tstate = NULL;
if(tcl_lock)PyThread_release_lock(tcl_lock);
if (result == 0)
Sleep(Tkinter_busywaitinterval);
Py_END_ALLOW_THREADS
#else
result = Tcl_DoOneEvent(0);
#endif
in bpo-31370, support for threads-less builds was removed, and this block became
Py_BEGIN_ALLOW_THREADS
if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = event_tstate;
result = Tcl_DoOneEvent(TCL_DONT_WAIT);
tcl_tstate = NULL;
if(tcl_lock)PyThread_release_lock(tcl_lock);
if (result == 0)
Sleep(Tkinter_busywaitinterval);
Py_END_ALLOW_THREADS
This is a bit unfortunate, as we now back to running a busy-wait loop. See Guido van Rossum's comment of May 23, 1998: 7bf15648
I guess this block could be
if (self->threaded) {
/* Allow other Python threads to run. */
ENTER_TCL
result = Tcl_DoOneEvent(0);
LEAVE_TCL
}
else {
Py_BEGIN_ALLOW_THREADS
if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = tstate;
result = Tcl_DoOneEvent(TCL_DONT_WAIT);
tcl_tstate = NULL;
if(tcl_lock)PyThread_release_lock(tcl_lock);
if (result == 0)
Sleep(Tkinter_busywaitinterval);
Py_END_ALLOW_THREADS
}
in analogy with the event loop in _tkinter_tkapp_mainloop_impl. As self->threaded is true in most builds, this would avoid the busy-wait loop.
I am happy to submit a PR, but I'll wait until PR #140147 is in to avoid unnecessary complications to this code.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans Modules/_tkinter.c, au niveau de EventHook, et comparez son bloc de boucle d’événements avec _tkinter_tkapp_mainloop_impl. Consultez PR #140147 avant de modifier ce code. Le travail est terminé lorsque Python interactif évite la boucle d’attente active dans les builds avec threads tout en conservant le comportement non threadé montré.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c, python
- Domaine
- desktop
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 55/100