]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Tue, 3 May 1994 14:15:01 +0000 (14:15 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 3 May 1994 14:15:01 +0000 (14:15 +0000)
Demo/threads/Generator.py [new file with mode: 0644]

diff --git a/Demo/threads/Generator.py b/Demo/threads/Generator.py
new file mode 100644 (file)
index 0000000..fbba06a
--- /dev/null
@@ -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()