Threading woes

David Allen s2mdalle at titan.vcu.edu
Fri Jan 26 18:46:35 EST 2001


Short summary: I'm writing a gopher client that works
in a way similar to a web browser, but far less complicated.
It uses Tkinter and Pmw.  Source in CVS if you want
to check out what I'm talking about (plus the program
is actually usable)
export CVSROOT=:pserver:anonymous at pi.complete.org:/var/cvs
cvs co clients/forg

Now my question.  I'm trying to implement a STOP button.
When the user clicks it, the program should stop what
it's doing *IMMEDIATELY* and go idle.  Currently
I've got STOP implemented, but it's horribly broken,
and only somewhat works half of the time.  :)

My first solution:  make the program threaded, and
have a "download thread" and a main thread.  The
main thread will do Tkinter type mainloop stuff,
and the download thread will, when the user requests,
go fetch stuff from the network.  This way the GUI
doesn't hang when downloading large things.

The way stop works this way is that each time it
steps through the read loop on the socket, it checks
a value which the main thread may have set to None.
If it's None, then it stops and returns immediately.
The problem with this is that it doesn't help for
calls which may block for a while, like gethostbyname
or even recv when you're recv'ing a large buffer.

In my recent other post, "Thread interruption", we
established that you can't throw exceptions in other
threads or signal yourself, so I'm pretty much at
a dead end with the threading solution with regard
to the STOP functionality.

So why not fork() processes, and then have them 
communicate via sockets or something?  For interruption,
I can just signal the download thread with SIGINT!
This would work, but fork is UNIX only, and I need portability
to at least windows.  Macs aren't that important
right now.  I'm developing on linux by default.

I know there's some technique I'm missing, or an
approach that I just don't know about.  I just need
a solution that meets 2 criteria:

- It allows my Tkinter GUI to not be hung, it processes
events as normal so if the user decides to grab a
40 terabyte file, the app doesn't hang.

- It is interruptable at any moment.  (i.e. if 
networking is down, and I call gethostbyname or recv, the
user doesn't have to wait for gethostbyname to fail
miserably before actually stopping)

What options do I have that haven't been discussed
yet?  It seems like a very simple problem, but I'm
lacking the right approach to solve this.

-- 
David Allen
http://opop.nols.com/



More information about the Python-list mailing list