[Tutor] Threaded FTP class
billburns at pennswoods.net
Tue Oct 10 03:28:05 CEST 2006
>> I'm trying to make a small, threaded FTP app and I'm running into
>> a problem.
>> My program has a GUI (I use PythonCard) and I want the GUI to be
>> responsive while network operations are going on.
>> I assumed that if I made a class (shown below) which was sub-classed
>> from threading.Thread - I wouldn't have any problems.
>> My GUI class (not shown) has a 'connect' button with a method that
>> looks like this:
>> def on_connect_command(self, event):
>> """Connect to the remote server."""
>> # getConnectData() -> returns a tuple with
>> # all of the data we need to connect.
>> server, username, password = self.getConnectData()
>> # Instantiate my threaded FTP class.
>> self.host = FTP(server, username, password)
>> When I hit this button, the GUI is completely responsive while trying to
>> connect to the remote server. I have no problems and everything works as
> In this method you create a new thread and start it. The thread's run()
> method is called. It connects to the remote server, fetches and prints a
> directory and returns. At that point (when the run() method returns) the
> FTP thread is dead.
>> Here's where I get the problem... The GUI class has another method which
>> looks like this:
>> def on_getData_command(self, event):
>> # getDirectoryData(...) is a method in the
>> # FTP() class. It walks a remote directory.
>> When I fire this method - it blocks until getDirectoryData() returns,
>> which makes the GUI non-responsive. It's *not* hanging due to a network
>> problem (it will only fire if you're connected to the remote server.)
>> Why does this one method block? I assumed it would run in the FTP class
>> thread and I'd have no problems!? What should I do different?
> No, you don't do anything here to make the getDirectoryData() method run
> in a separate thread. Just because the FTP class has (or had) one thread
> at one time doesn't automatically make all of the FTP class methods run
> in a different thread.
> There are a few different ways you could handle this. You could have
> each command in the FTP class be smart enough to start a new thread to
> run the command. You don't actually have to subclass threading.Thread,
> you can just create a thread and tell it what method to execute. (Side
> note - this might be a good use for a @run_in_thread decorator.)
> You could make a separate class for each command. This would be pretty
> similar to the above solution. You would probably want a base class or
> utility class to hold the common details of connecting and sending a
> You could make a thread that really does keep running, that listens to
> for commands from a Queue. Your GUI thread would put a command in the
> Queue, the daemon thread would pull a command out and execute it.
> You could figure out how to do this with Twisted...
Thank you for the explanation and ideas!! I wasn't exactly sure how the
threading was working but you've enlightened me!
More information about the Tutor