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.