annotate Demo/threads/Generator.py @ 4566:6403c94de50d legacy-trunk

Added safeguard against failure in __del__.
author Guido van Rossum <guido@python.org>
date Wed, 27 Nov 1996 19:39:58 +0000
parents 301f8ca98e0b
children c1824d68d10e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1600
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 # Generator implementation using threads
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 import thread
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 Killed = 'Generator.Killed'
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 class Generator:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
8 # Constructor
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
9 def __init__(self, func, args):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 self.getlock = thread.allocate_lock()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 self.putlock = thread.allocate_lock()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 self.getlock.acquire()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
13 self.putlock.acquire()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 self.func = func
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 self.args = args
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 self.done = 0
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 self.killed = 0
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 thread.start_new_thread(self._start, ())
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
19 # Internal routine
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 def _start(self):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 try:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 self.putlock.acquire()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 if not self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 try:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 apply(self.func, (self,) + self.args)
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26 except Killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 pass
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 finally:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 if not self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 self.done = 1
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 self.getlock.release()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
32 # Called by producer for each value; raise Killed if no more needed
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 def put(self, value):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
34 if self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 raise TypeError, 'put() called on killed generator'
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 self.value = value
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 self.getlock.release() # Resume consumer thread
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 self.putlock.acquire() # Wait for next get() call
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 if self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 raise Killed
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 # Called by producer to get next value; raise EOFError if no more
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 def get(self):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 if self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 raise TypeError, 'get() called on killed generator'
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 self.putlock.release() # Resume producer thread
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 self.getlock.acquire() # Wait for value to appear
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 if self.done:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 raise EOFError # Say there are no more values
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 return self.value
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 # Called by consumer if no more values wanted
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 def kill(self):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 if self.killed:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 raise TypeError, 'kill() called on killed generator'
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 self.killed = 1
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 self.putlock.release()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 # Clone constructor
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 def clone(self):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 return Generator(self.func, self.args)
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 def pi(g):
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
62 while 1:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 # Next approximation
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 p, q, k = k*k, 2L*k+1L, k+1L
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 # Print common digits
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 d, d1 = a/b, a1/b1
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
68 while d == d1:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 g.put(int(d))
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
70 a, a1 = 10L*(a%b), 10L*(a1%b1)
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 d, d1 = a/b, a1/b1
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
72
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 def test():
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
74 g = Generator(pi, ())
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 g.kill()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 g = Generator(pi, ())
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 for i in range(10): print g.get(),
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 print
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 h = g.clone()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 g.kill()
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 while 1:
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 print h.get(),
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
83
301f8ca98e0b Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 test()