Fun Little Threading Problem

August 26, 2011 at 04:06 PM | Play | View Comments

A fun little threading problem I ran into today: imagine a Thermometer which can issue notifications if the temperature reaches a certain threshold:

class Thermometer(object):
    def set_temperature(self, value):
        self.temperature = value

    def wait_for_temperature(self, target):
        # ... wait for `self.temperature` to be at least `target` ...
        return self.temperature

Using only AsyncResult, how can the set_temperature and wait_for_temperature methods be implemented to guarantee that multiple threads can wait_for_temperature without missing a temperature change (only one thread will be call set_temperature).

My solution:

class Thermometer(object):
    def __init__(self):
        self.temperature_changed = AsyncResult()

    def set_temperature(self, value):
        self.temperature = value
        next_change = AsyncResult()
        self.temperature_changed.set((next_change, value))
        self.temperature_changed = next_change

    def wait_for_temperature(self, target):
        changed = self.temperature_changed
        temperature = self.temperature
        while temperature < target:
            changed, temperature = changed.get()
        return temperature

I originally encountered this problem working on a component at work, but I enjoyed the solution so I thought I would adapt it and post it here.