Re: Threading, real or simulated?

Discussion in 'Python' started by Jp Calderone, Sep 22, 2005.

  1. Jp Calderone

    Jp Calderone Guest

    On Wed, 21 Sep 2005 18:23:33 -0500, Sam <> 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.

    >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.

    Jp
     
    Jp Calderone, Sep 22, 2005
    #1
    1. Advertising

  2. Jp Calderone

    Sam Guest

    Jp Calderone writes:

    > On Wed, 21 Sep 2005 18:23:33 -0500, Sam <> 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.



    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.7 (GNU/Linux)

    iD8DBQBDMfXwx9p3GYHlUOIRAnIsAJ9N8v/diswTPGByKjAu8fkXllfi9ACfQSdi
    kCbZpvcx4E5vJC90RLhka+U=
    =tp+g
    -----END PGP SIGNATURE-----
     
    Sam, Sep 22, 2005
    #2
    1. Advertising

  3. Op 2005-09-22, Sam schreef <>:
    > Jp Calderone writes:
    >
    >> On Wed, 21 Sep 2005 18:23:33 -0500, Sam <> 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 general interpretor lock. In general changing python internals
    is not thread-safe. The current implementation uses a lock (the GIL)
    for thread to safely rebind variable or mutate object. The result
    is that threads are serialised.

    > 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:


    Yes you have locked the GIL. Take a look at the following
    URL: http://docs.python.org/api/threads.html, hope it helps.

    --
    Antoon Pardon
     
    Antoon Pardon, Sep 22, 2005
    #3
  4. Jp Calderone

    Peter Hansen Guest

    Antoon Pardon wrote:
    > Op 2005-09-22, Sam schreef <>:
    >>What's the GIL?.

    >
    > The general interpretor lock. In general changing python internals


    That should be "global" (and, more pedantically, "interpreter").
     
    Peter Hansen, Sep 22, 2005
    #4
  5. Jp Calderone

    Sam Guest

    Antoon Pardon writes:

    >>> 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:

    >
    > Yes you have locked the GIL. Take a look at the following
    > URL: http://docs.python.org/api/threads.html, hope it helps.


    Yes, thank you. That was it.

    Since I was creating threads, and messing with them, in pure Python with
    threading.Thread, I never had an opportunity to read this part of the API
    spec.



    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.7 (GNU/Linux)

    iD8DBQBDMzk5x9p3GYHlUOIRAmbsAJ420FRjDetVTHe3imEvsh3ys4E6NACfQNun
    7YXHyxkl6E1B+iqCbbJFMGk=
    =8uQO
    -----END PGP SIGNATURE-----
     
    Sam, Sep 23, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. stan k.
    Replies:
    1
    Views:
    663
    John C. Bollinger
    Sep 23, 2003
  2. Jochus
    Replies:
    3
    Views:
    496
  3. Sean Berry
    Replies:
    2
    Views:
    371
    David M. Cooke
    Apr 26, 2004
  4. Sam
    Replies:
    0
    Views:
    261
  5. Replies:
    6
    Views:
    672
Loading...

Share This Page