Persistent Threads & Synchronisation

Marc 'BlackJack' Rintsch bj_666 at gmx.net
Sun Nov 26 13:24:21 CET 2006


In <ekbtta$753$1 at news.freedom2surf.net>, Matthew Tylee Atkinson wrote:

> They way I want it to work is this:  The downloading thread, when
> spawned, stays alive for the duration of the program.  Occasionally the
> main program will call a function in it to download the data and save it
> as files on disk.  Then, these files are loaded by the main thread.
> When this has happened, the main thread calls another function in the
> download thread to delete the temporary files.  The same thing happens
> next time a download is needed, when the user is looking at some other
> content.
> 
> My problem is this: the downloading thread only seems to execute code
> in a separate thread as long as the run() function (called by the
> start() function) is running.  This is as per the documentation, of
> course.  I am performing the download in the run() function, but the
> file cleanup is still done with a separate call.  This actually does
> work, after the download is over, and run() has terminated, but I
> believe it isn't happening in a separate thread anymore (as previously I
> made a mistake and called run() directly, instead of start() and it
> blocked the main program).

There seems to be a misunderstanding of threads.  You don't call functions
in a thread from the main program.  If you call a function from the main
thread then the function is executed in the main thread.  That's true for
any call on `Thread` objects except for `start()` which really starts
executing the `run()` method in a separate thread.

The easiest way for safe communication with threads is a `Queue` like
the one in the `Queue` module.  If you want a download thread that
is running alongside the main program all the time then write a while loop
that gets "commands" via a queue.  Something like:

    def run(self):
        while True:
            command = self.queue.get()
            if command == 'exit':
                break
            # ...

    def exit(self):
        self.queue.put('exit')

    # ...

Of course the `command` objects can be more complex than strings to hold
arguments for the worker thread.

> I did wonder about using a Condition, but that seems to be more suited
> for synchronising between threads, which isn't really the issue here
> (and thus it seems like overkill for solving the problem of replacing
> that loop with something more efficient, though could be a possibility,
> I suppose).

But that problem *is* about thread synchronization.

Ciao,
	Marc 'BlackJack' Rintsch



More information about the Python-list mailing list