From 5e49d8f5ef6687c9ed896f5350c167eb78191c0c Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Fri, 4 Sep 2015 14:30:44 -0500 Subject: [PATCH] Add: Completed demo. --- tutorial/threading_demo.py | 57 +++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/tutorial/threading_demo.py b/tutorial/threading_demo.py index 9e74580..e5c7449 100644 --- a/tutorial/threading_demo.py +++ b/tutorial/threading_demo.py @@ -4,49 +4,68 @@ # threading.py - Threads in Python. # **************************************************** # Threads are easy to get subtly wrong. - +# # Library imports # =============== from threading import Thread, Lock from time import sleep - -# A class to produce numbers. +# +# NumberFactory - A class to produce numbers. +# =========================================== class NumberFactory(object): - def __init__(self): + def __init__(self, + # A Lock instance to enforce exclusive access. + lock): + self._number = 0 + self._lock = lock + # Get a unique number from the factory. def get_number(self): - self._number += 1 - return self._number - -# Create a class that counts. + # A context manager makes using a lock `easy `_. + with self._lock: + self._number += 1 + sleep(0.5) + return self._number +# +# CounterThread - a class that counts in a separate thread. +# ================================================================= class CounterThread(Thread): def __init__(self, - # A lock, needed before getting a number. - lock, # Time to wait before getting a new number, in seconds. wait_time_sec, # Class to get numbers from. - number_factory): + number_factory, + # Any extra args. + **kwargs): - Thread.__init__(self) - self._lock = lock + # Thread.__init__ `must `_ be called. To invoke a parent, common syntax is ``Thread.__init__(self, kwargs)``. This has several problems, however; use the (awkward) `super `_ syntax instead. Note that this syntax is much improved in Python 3 -- simply use `super().__init__(kwargs) `_. + super(CounterThread, self).__init__(**kwargs) self._wait_time_sec = wait_time_sec self._number_factory = number_factory + # `This method `_ runs in a separate thread. def run(self): for index in range(10): sleep(self._wait_time_sec) print('{}: {}'.format(self.name, self._number_factory.get_number())) - +# +# main -- run the threads +# ======================= def main(): - nf = NumberFactory() + # Create two threads. + # + # Use a `lock `_ to enforce exclusive access in the NumberFactory. lock = Lock() - ct1 = CounterThread(lock, 1.5, nf, name='Slow') - ct2 = CounterThread(lock, 1.0, nf, name='Fast') - ct1.run() - ct2.run() + nf = NumberFactory(lock) + ct1 = CounterThread(1.0, nf, name='Slow') + ct2 = CounterThread(0.75, nf, name='Fast') + + # Run them. + ct1.start() + ct2.start() + # Wait for both of them to finish. ct1.join() ct2.join()