summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Demo/threads/Generator.py84
1 files changed, 84 insertions, 0 deletions
diff --git a/Demo/threads/Generator.py b/Demo/threads/Generator.py
new file mode 100644
index 0000000..fbba06a
--- /dev/null
+++ b/Demo/threads/Generator.py
@@ -0,0 +1,84 @@
+# Generator implementation using threads
+
+import thread
+
+Killed = 'Generator.Killed'
+
+class Generator:
+ # Constructor
+ def __init__(self, func, args):
+ self.getlock = thread.allocate_lock()
+ self.putlock = thread.allocate_lock()
+ self.getlock.acquire()
+ self.putlock.acquire()
+ self.func = func
+ self.args = args
+ self.done = 0
+ self.killed = 0
+ thread.start_new_thread(self._start, ())
+ # Internal routine
+ def _start(self):
+ try:
+ self.putlock.acquire()
+ if not self.killed:
+ try:
+ apply(self.func, (self,) + self.args)
+ except Killed:
+ pass
+ finally:
+ if not self.killed:
+ self.done = 1
+ self.getlock.release()
+ # Called by producer for each value; raise Killed if no more needed
+ def put(self, value):
+ if self.killed:
+ raise TypeError, 'put() called on killed generator'
+ self.value = value
+ self.getlock.release() # Resume consumer thread
+ self.putlock.acquire() # Wait for next get() call
+ if self.killed:
+ raise Killed
+ # Called by producer to get next value; raise EOFError if no more
+ def get(self):
+ if self.killed:
+ raise TypeError, 'get() called on killed generator'
+ self.putlock.release() # Resume producer thread
+ self.getlock.acquire() # Wait for value to appear
+ if self.done:
+ raise EOFError # Say there are no more values
+ return self.value
+ # Called by consumer if no more values wanted
+ def kill(self):
+ if self.killed:
+ raise TypeError, 'kill() called on killed generator'
+ self.killed = 1
+ self.putlock.release()
+ # Clone constructor
+ def clone(self):
+ return Generator(self.func, self.args)
+
+def pi(g):
+ k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
+ while 1:
+ # Next approximation
+ p, q, k = k*k, 2L*k+1L, k+1L
+ a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
+ # Print common digits
+ d, d1 = a/b, a1/b1
+ while d == d1:
+ g.put(int(d))
+ a, a1 = 10L*(a%b), 10L*(a1%b1)
+ d, d1 = a/b, a1/b1
+
+def test():
+ g = Generator(pi, ())
+ g.kill()
+ g = Generator(pi, ())
+ for i in range(10): print g.get(),
+ print
+ h = g.clone()
+ g.kill()
+ while 1:
+ print h.get(),
+
+test()