Hilo seguro Python GTK + 3

Entonces, ¿qué debo ejecutar al principio de mi progtwig para que sea seguro para subprocesos (o que tenga en cuenta los subprocesos como he leído en algunos lugares):

from gi.repository import Gtk, Gdk, GLib, GObject import threading GLib.threads_init() # ? GObject.threads_init() # YES! Gdk.threads_init() # ? my_app() def my_threaded_func(): Glib.idle_add(lambda: some_gui_action()) Glib.timeout_add(300, lambda: some_gui_action()) t = threading.Thread(target=my_thread_func) t.daemon = True t.start() Gtk.main() 

Entonces, ¿qué debo hacer en mis hilos? ¿Algún tipo de cerradura? ¿Es seguro usar la librería de hilos de Python o debo usar algo en GLib, GObject o Gdk? Sé que hay un montón de preguntas / respuestas / ejemplos por ahí, pero todos se contradicen entre sí, no son para Gtk + 3, o no para Python, o simplemente están incompletos, e incluso lo que consideré los documentos oficiales de Python GI ( http : //lazka.github.io/pgi-docs/ ) ni siquiera menciona la existencia de GObject.threads_init () y Gdk.threads_init ().

Related of "Hilo seguro Python GTK + 3"

https://wiki.gnome.org/Projects/PyGObject/Threading

.. pero, Gdk.threads_init () está en desuso , y lo recomiendo:

  • No llamar a Gdk.threads_init, Gdk.threads_enter / leave en absoluto
  • Use GLib.idle_add en lugar de Gdk.threads_add_idle (o cualquier otra función Gdk.threads_ *)
  • Empuje las cosas que tocan Gdk / Gtk al hilo principal usando GLib.idle / timeout_add

¿Por qué?:

  • No llamar a Gdk.threads_init significa que no habrá locking, lo cual está bien si nunca accede a GDK desde otro hilo.
  • Gdk.threads_enter no hace nada ya que no hay locking.
  • GLib.idle_add es igual a Gdk.threads_add_idle en este caso.

Respecto a otras libs:

  • Algunos módulos GI pueden emitir ciertas señales / devoluciones de llamada en otros subprocesos (en GStreamer, la señal de GstPlayBin :: sobre-para-terminar, por ejemplo); incluso si no utilizas hilos de Python en tu código en absoluto. El código Gdk / Gtk no se puede llamar directamente en ellos, use idle_add allí también si es necesario.
  • Muchas partes de GLib / GStreamer son seguras para subprocesos y pueden llamarse desde otros subprocesos.

tl; dr: Solo GObject.threads_init () , en los subprocesos, empujan todo el código Gtk / Gdk al subproceso principal usando GLib.idle_add

Aquí hay que leer el documento si alguien va a usar GTK en código de multiproceso. https://wiki.gnome.org/Attic/GdkLock

Este documento realmente me ayudó a entender cómo ejecutar GTK desde C así como desde python (a través de PyGTK solo para importar gtk en python) en un solo proceso. Aunque el locking GDK se puede evitar en Linux con XInitThreads() no es una solución para Windows. Las funciones como g_idle_add() o g_timeout_add() son la solución genérica para evitar el aplastamiento de GUI. Sin embargo, gdk_threads_enter () y gdk_thread_leave () aún no son completamente inútiles. Ese documento aclara cómo usar esos lockings de forma segura si alguien desea actualizar la GUI desde diferentes subprocesos o desde un controlador de eventos personalizado o desde devoluciones de llamada g_idle_add() .