what thread-synch mech to use for clean exit from a thread

Steven D'Aprano steve at pearwood.info
Sun Jul 14 23:04:14 EDT 2013


On Mon, 15 Jul 2013 10:27:45 +0800, Gildor Oronar wrote:

> A currency exchange thread updates exchange rate once a minute. If the
> thread faield to update currency rate for 5 hours, it should inform
> main() for a clean exit. This has to be done gracefully, because main()
> could be doing something delicate.
> 
> I, a newbie, read all the thread sync tool, and wasn't sure which one to
> use. In fact I am not sure if there is a need of thread sync, because
> there is no racing cond. I thought of this naive way:
> 
> class CurrencyExchange():
>     def __init__(in_case_callback):
>        this.callback = in_case_callback

You need to declare the instance parameter, which is conventionally 
called "self" not "this". Also, your class needs to inherit from Thread, 
and critically it MUST call the superclass __init__.

So:

class CurrencyExchange(threading.Thread):
    def __init__(self, in_case_callback):
        super(CurrencyExchange, self).__init__()
        self.callback = in_case_callback

But I'm not sure that a callback is the right approach here. See below.


>     def __run__():

Likewise, you need a "self" parameter.


>        while time.time() - self.rate_timestamp < 5*3600:
>           ... # update exchange rate
>           if success:
>              self.rate_timestamp == time.time()
>           time.sleep(60)
>        this.callback() # rate not updated 5 hours, a crisis

I think that a cleaner way is to just set a flag on the thread instance. 
Initiate it with:

    self.updates_seen = True

in the __init__ method, and then add this after the while loop:

    self.updates_seen = False


 
> def main():
>     def callback()
>        Go_On = False

I don't believe this callback will work, because it will simply create a 
local variable call "Go_On", not change the non-local variable.

In Python 3, you can use the nonlocal keyword to get what you want, but I 
think a better approach is with a flag on the thread.

>     agio = CurrencyExchange(in_case = callback) 
>     agio.start()
> 
>     Go_On = True
>     while Go_On:
>        do_something_delicate(rate_supplied_by=agio)

Change to:

    while agio.updates_seen:
        do_something_delicate...


-- 
Steven



More information about the Python-list mailing list