Jp Calderone writes:

On Wed, 21 Sep 2005 18:23:33 -0500, Sam <[EMAIL PROTECTED]> wrote:
I'm using Python 2.3.5 with pygtk 2.4.1, and I'm using the second threading approach from pygtk's FAQ 20.6 - invoking "gtk.gdk.threads_init()", and wrapping all gtk/gdk function calls with gtk.threads_enter()/gtk.threads_leave()

I start a thread, via thread.Threading.start(). The thread then calls a particularly time consuming C function, from an extension module. I find that when the thread is running the C code, the GUI hangs even though I'm not inside the threads_enter/threads_leave territory.


  Does the extension module release the GIL?  It sounds like it does not.  Of 
course, there are a dozen other mistakes that could be made which would have 
roughly this symptom.  It's difficult to say which is the problem without 
actually seeing any code.

What's the GIL?. The extension module is invoked outside of threads_enter/threads_leave().

It looks like thread.Threading() only simulates threading, by having the python interpreter multiplex between running threads. Is real threading possible, so that I do something time-consuming in the thread, without hanging the GUI?


Assuming you mean threading.Thread, this is a native thread.  It is not a 
simulation.  Something else is going wrong.

Then I must have something locked.  Here's what I do:

   gtk.gdk.threads_init()
   mainwindow=MainWindow()
   gtk.threads_enter()
   gtk.main()
   gtk.threads_leave()


The code in MainWindow.__init__() does this:

       self.__window=gtk.Window(gtk.WINDOW_TOPLEVEL)
       self.__window.set_default_size(600, 600)

       [ some more initialization ]

       self.__window.show_all()
       self.__window.connect("delete-event", self.delete_event)
       self.__window.connect("destroy", self.destroy)

       t=self.initializationThread()
       t.packageLayout=packageLayout
       t.start()

Here's the definition of my initializationThread class:

   class initializationThread(threading.Thread):
       def run(self):
           gtk.threads_enter()
           busy_cursor=gtk.gdk.Cursor(gtk.gdk.WATCH)
           self.packageLayout.window.set_cursor(busy_cursor)
           gtk.threads_leave()


I do get a busy cursor at this point, so I know that this thread is running. initializationThread.run() continues, as follows:

           try:
               sysrep=lpm.getSystemRepository()
               pkgs=sysrep.getPackages()
               pkgs.sort()
               for i in pkgs:
                   icon=sysrep.getManifest(i).header("Icon")
                   gtk.threads_enter()
                   try:
                       if self.packageLayout.window == None:
                           break      # Someone was impatient
                       self.packageLayout.addPackage(i, icon)
                   finally:
                       gtk.threads_leave()


lpm.getSystemRepository() instantiates an object of an extension-defined type. It's getPackages() method returns a list of objects that are also of an extension-defined type, which I then iterate over. Each iteration invokes the getManifest() method of an extension-defined type.

All the stuff between gtk.threads_enter() and gtk.threads_leave() runs pure python code, and should be nearly instantaneous. Furthermore, gtk functions that end up being invoked in the addPackage() method, provide some GUI feedback. Each addPackage() iteration adds a new widget in the main window.

Occasionally, there's a noticeable delay, before a new widget appears, because there's a lot on getManifest()'s plate. I get no response from any GUI activity, during the delay. getManifest() gets invoked outside the threads_enter/threads_leave lock, but the GUI is still hanging when that happens.


Attachment: pgp1CNTdr48aH.pgp
Description: PGP signature

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to