python / python/cpython

tkinter runs a busy-wait loop on interactive Python

Abierto
#140,488 5 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

extension-modules topic-tkinter type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza en Modules/_tkinter.c, en EventHook, y compara su bloque del bucle de eventos con _tkinter_tkapp_mainloop_impl. Revisa PR #140147 antes de cambiar este código. Se considera terminado cuando Python interactivo evita el bucle de espera activa en las compilaciones con hilos, preservando al mismo tiempo el comportamiento mostrado sin hilos.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
c, python
Área
desktop
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
55/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.