Further refined section on logging to one file from multiple processes.
[python.git] / Demo / threads / Generator.py
blob2e814a0c5e10c9561d73542df5d73511b49e1ca3
1 # Generator implementation using threads
3 import sys
4 import thread
6 class Killed(Exception):
7 pass
9 class Generator:
10 # Constructor
11 def __init__(self, func, args):
12 self.getlock = thread.allocate_lock()
13 self.putlock = thread.allocate_lock()
14 self.getlock.acquire()
15 self.putlock.acquire()
16 self.func = func
17 self.args = args
18 self.done = 0
19 self.killed = 0
20 thread.start_new_thread(self._start, ())
22 # Internal routine
23 def _start(self):
24 try:
25 self.putlock.acquire()
26 if not self.killed:
27 try:
28 apply(self.func, (self,) + self.args)
29 except Killed:
30 pass
31 finally:
32 if not self.killed:
33 self.done = 1
34 self.getlock.release()
36 # Called by producer for each value; raise Killed if no more needed
37 def put(self, value):
38 if self.killed:
39 raise TypeError, 'put() called on killed generator'
40 self.value = value
41 self.getlock.release() # Resume consumer thread
42 self.putlock.acquire() # Wait for next get() call
43 if self.killed:
44 raise Killed
46 # Called by producer to get next value; raise EOFError if no more
47 def get(self):
48 if self.killed:
49 raise TypeError, 'get() called on killed generator'
50 self.putlock.release() # Resume producer thread
51 self.getlock.acquire() # Wait for value to appear
52 if self.done:
53 raise EOFError # Say there are no more values
54 return self.value
56 # Called by consumer if no more values wanted
57 def kill(self):
58 if self.killed:
59 raise TypeError, 'kill() called on killed generator'
60 self.killed = 1
61 self.putlock.release()
63 # Clone constructor
64 def clone(self):
65 return Generator(self.func, self.args)
67 def pi(g):
68 k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
69 while 1:
70 # Next approximation
71 p, q, k = k*k, 2L*k+1L, k+1L
72 a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
73 # Print common digits
74 d, d1 = a//b, a1//b1
75 while d == d1:
76 g.put(int(d))
77 a, a1 = 10L*(a%b), 10L*(a1%b1)
78 d, d1 = a//b, a1//b1
80 def test():
81 g = Generator(pi, ())
82 g.kill()
83 g = Generator(pi, ())
84 for i in range(10): print g.get(),
85 print
86 h = g.clone()
87 g.kill()
88 while 1:
89 print h.get(),
90 sys.stdout.flush()
92 test()