wxPython and threads again

Bryan Olson fakeaddress at nowhere.org
Wed Aug 10 14:35:27 EDT 2005


David E. Konerding DSD staff wrote:
[...]
 > You need another way to pass completion information between the 
downloader
 > thread and the main thread; the simplest way is to define a custom wx
 > Event, and wxPostEvent from the downloader thread when it completes (
 > and when the gauge should be updated).  wxPostEvent is safe to call 
from non-eventloop threads.
 > The main thread's wx event loop just spins, properly updating all other
 > parts of the GUI, and receiving events from the downloader thread.
 >
 > ANother approach is to have a thread-safe Queue and have the main 
thread/event loop
 > poll the queue with queue.get_nowait() periodically (typically 0.1-1 
sec).
 > The downloader thread shares the queue object and puts data 
structures (typically
 > class instances, strings, or ints) that indicate status updates.

The way-cool things to transmit, in either the queue or the
event data, are tuples of:

     (func, args, kwargs)

The so-called-'main' thread gets these, and blindly calls
func(*args, **kwargs). Since only the main thread can safely
update the GUI, other threads pass GUI-updating functions to be
called by the main thread.

The technique is beautifully general. The worker thread does
it's long, blocking operations independently, and when it needs
to update the GUI it sends the main thread a quick, non-blocking
function.

In wxPython, custom events can carry arbitrary data, so the easy
thing to do is just pass the (func, args, kwargs) across with
wxPostEvent (or so I've read; I'm not a wxPython user).

TkInter has no equivalent to wxPostEvent. Contrary to popular
belief, TkInter's event_generate is not thread-safe. The usual
TkInter solution is a queue, which the main thread periodically
polls via the 'after' function.


 > The easiest approach, though, is to use the threadedselectreactor in 
Twisted (you need
 > to check the HEAD branch out with subversion, because that reactor 
isn't included in any releases).
 > With threadedselectreactor, it's easy to incorporate both the GUI 
event loop and the twisted reactor.
 > Twisted already includes lots of code for doing asynchronous 
callback-style IO for
 > IO bound processes like downloading.  Further, you don't even think 
in an explicitly threaded way-
 > createing a whole thread just to manage a download process which is 
motly IO and a little bookkeeping is
 > silly.  Twisted's approach just makes a lot more sense and simplifies 
the code too.

I couldn't disagree more about that being easier and simplifying
the code. "Creating a whole thread" is trivial.


-- 
--Bryan



More information about the Python-list mailing list