Question

I have a PyGtk (GTK+ 3) application that runs in two threads:

  • Thread A is a main app thread that executes Gtk.main() and so handles Gtk's events/signals.
  • Thread B is a PulseAudio event thread that handles all PA's stuff asynchronously.

In certain cases it's necessary to make an event handled by a callback from thread B do something in Gtk objects. The problem with Python is that because of GIL only one thread can run at a time, so it's not possible to change any Gtk-related things directly — it results in a deadlock.

A solution to it might be calling Gdk.threads_init() to allow GIL to be lifted for Gtk, but that seems to result in race conditions, apparently Gtk is not thread-safe enough.

What I want to do is 'flatten out' event handling so that thread B leaves something (event/signal?) for thread A to pick up and handle. in this scenario thread B is not blocked by this operation. As far as I understand, this is not the case with Python's signalling mechanism because it handles signals synchronously.

So my question is: how can I create a sort of custom event that can be picked up by Gtk's main loop and processed by thread A code?

Was it helpful?

Solution

Gtk is NOT threadsafe, you have to write your code so that it is threadsafe.

I don't know what version of pygtk you're using, but the easiest way to queue an action on the GUI thread is with idle_add:

http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--idle-add

It queue's a function in Gtk's main loop and will get executed on it's thread.

EDIT: This is just the easiest way to get a function called on the GUI thread. If you want do the work of creating a custom gobject signal, I believe (but am not 100% sure) that the signal handler will be called on the GUI thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top