[pygtk] PyGTK deadlocks... I know, right?

Robert Schroll rschroll at gmail.com
Sun Jan 13 00:51:23 WST 2013


First, a disclaimer:  I don't grok threads, so what I'm saying may be 
wrong.  If someone else says differently, believe them.  But I think 
I've figured out what's going on.

On 01/12/2013 06:24 AM, Niklas Koep wrote:
> Here's one. I'm using PyGTK 2.24 with gstreamer 0.10.36. Whenever
> gstreamer reports an error on my playbin2's message bus I display the
> error in a gtk.MessageDialog. This causes the app to deadlock unless I
> use a context manager with gtk.gdk.lock. At first I suspected a
> threading issue, but according to the gstreamer docs messages on the bus
> are emitted from the main thread so I don't see how threading could be
> an issue.  Nevertheless, I verified this by retrieving the thread ids
> with libc via ctypes and they're identical.

I suspect your reasoning is faulty [1], but your conclusion is correct: 
the signal handlers will be called in the main thread.  But why would 
you expect them to be called inside the GDK lock?  The whole point of 
calling threads_init, as I understand it, is to tell the main loop to 
release the lock occasionally so that you can grab it in another thread. 
  So no matter what thread you're in, you need to grab the lock when you 
need it.  (And if you're doing anything GTKish, you need it.)  The need 
for the lock in your sample program makes sense.

But do you actually need a threaded pyGTK?  GStreamer will use as many 
threads as it deems necessary completely independently of whether you 
set up threading in Python (I think).  So you can also get your sample 
program to work by taking out the two threads_init() calls as well as 
the gtk.gdk.lock.  Maybe your real program does need threads, but what 
you've shown us certainly doesn't [2].

Hope that helps,
Robert

[1] I suspect you were looking here 
(http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bus.html), 
where it says that bus handlers will be called from the main thread. 
But you're not using those; you're using a GSignals-based approach.  The 
signal handlers will also be called from the main thread, which explains 
your results.

[2] Note that you can also write a threaded Python program, but leave 
the GTK part single-threaded.  If you take out your 
gtk.gdk.threads_init() call, you can also take out the gtk.gdk.lock. 
You can use multiple threads in Python now, but you can only do GTK 
stuff from the main thread.  This isn't actually that much of a 
restriction -- if you want to GTK stuff from a secondary thread, you 
just put that code into gobject.idle_add().  It will then be executed in 
the main thread (which always has the GDK lock in this approach) when 
there's time.  Personally, I find this way of thinking easier, but I try 
to avoid threads completely if at all possible.


More information about the pygtk mailing list