""" The purpose of this file is to demonstrate how one might use a condition variable to obtain mutual exclusion and waiting for a condition. """ from threading import Thread, Condition class CollatzEven(Thread): """The even number case of the https://en.wikipedia.org/wiki/Collatz_conjecture n → n÷2 if n is even and greater than 1""" def __init__(self, mutable, cv): Thread.__init__(self) self.value = mutable self.steps = 0 self.cv = cv def run(self): with self.cv: while True: while (self.value[0] > 1) and (self.value[0] % 2): self.cv.wait() if self.value[0] <= 1: break print(self.value[0], end=' → ') self.value[0] //= 2 print(self.value[0]) self.steps += 1 self.cv.notify() class CollatzOdd(Thread): """The odd number case of the https://en.wikipedia.org/wiki/Collatz_conjecture n → 3n+1 if n is odd and greater than 1""" def __init__(self, mutable, cv): Thread.__init__(self) self.value = mutable self.steps = 0 self.cv = cv def run(self): with self.cv: while True: while (self.value[0] > 1) and not (self.value[0] % 2): self.cv.wait() if self.value[0] <= 1: break print(self.value[0], end=' → ') self.value[0] *= 3 self.value[0] += 1 print(self.value[0]) self.steps += 1 self.cv.notify() cv = Condition() start = 340 value = [start] # in a list because lists are mutable ts = [ CollatzEven(value, cv), CollatzOdd(value, cv) ] for t in ts: t.start() for t in ts: t.join() print(f'Collatz({start}) resulted in', value[0], 'after',ts[0].steps,'even-number steps and',ts[1].steps,'odd-number steps')