Mercurial > cpython-lru_cache-weakref
annotate Demo/threads/Generator.py @ 79675:c0a2294de787 2.7
Issue #16199: Backport 2to3 typo fix from 3.2.
| author | Chris Jerdonek <chris.jerdonek@gmail.com> |
|---|---|
| date | Thu, 11 Oct 2012 16:15:46 -0700 |
| parents | 0932b9baa7a4 |
| children |
| rev | line source |
|---|---|
| 1600 | 1 # Generator implementation using threads |
| 2 | |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
3 import sys |
| 1600 | 4 import thread |
| 5 | |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
6 class Killed(Exception): |
|
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
7 pass |
| 1600 | 8 |
| 9 class Generator: | |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
10 # Constructor |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
11 def __init__(self, func, args): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
12 self.getlock = thread.allocate_lock() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
13 self.putlock = thread.allocate_lock() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
14 self.getlock.acquire() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
15 self.putlock.acquire() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
16 self.func = func |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
17 self.args = args |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
18 self.done = 0 |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
19 self.killed = 0 |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
20 thread.start_new_thread(self._start, ()) |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
21 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
22 # Internal routine |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
23 def _start(self): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
24 try: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
25 self.putlock.acquire() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
26 if not self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
27 try: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
28 apply(self.func, (self,) + self.args) |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
29 except Killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
30 pass |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
31 finally: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
32 if not self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
33 self.done = 1 |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
34 self.getlock.release() |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
35 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
36 # Called by producer for each value; raise Killed if no more needed |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
37 def put(self, value): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
38 if self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
39 raise TypeError, 'put() called on killed generator' |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
40 self.value = value |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
41 self.getlock.release() # Resume consumer thread |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
42 self.putlock.acquire() # Wait for next get() call |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
43 if self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
44 raise Killed |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
45 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
46 # Called by producer to get next value; raise EOFError if no more |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
47 def get(self): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
48 if self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
49 raise TypeError, 'get() called on killed generator' |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
50 self.putlock.release() # Resume producer thread |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
51 self.getlock.acquire() # Wait for value to appear |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
52 if self.done: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
53 raise EOFError # Say there are no more values |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
54 return self.value |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
55 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
56 # Called by consumer if no more values wanted |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
57 def kill(self): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
58 if self.killed: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
59 raise TypeError, 'kill() called on killed generator' |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
60 self.killed = 1 |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
61 self.putlock.release() |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
62 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
63 # Clone constructor |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
64 def clone(self): |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
65 return Generator(self.func, self.args) |
| 1600 | 66 |
| 67 def pi(g): | |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
68 k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
69 while 1: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
70 # Next approximation |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
71 p, q, k = k*k, 2L*k+1L, k+1L |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
72 a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1 |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
73 # Print common digits |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
74 d, d1 = a//b, a1//b1 |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
75 while d == d1: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
76 g.put(int(d)) |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
77 a, a1 = 10L*(a%b), 10L*(a1%b1) |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
78 d, d1 = a//b, a1//b1 |
| 1600 | 79 |
| 80 def test(): | |
|
32746
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
81 g = Generator(pi, ()) |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
82 g.kill() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
83 g = Generator(pi, ()) |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
84 for i in range(10): print g.get(), |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
85 print |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
86 h = g.clone() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
87 g.kill() |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
88 while 1: |
|
c1824d68d10e
Whitespace normalization. Had to break guido's lock on rev 1.1 to do
Tim Peters <tim.peters@gmail.com>
parents:
1600
diff
changeset
|
89 print h.get(), |
|
49161
0932b9baa7a4
#687648 from Robert Schuppenies: use classic division. From me: don't use string exception; flush stdout after printing
Andrew M. Kuchling <amk@amk.ca>
parents:
32746
diff
changeset
|
90 sys.stdout.flush() |
| 1600 | 91 |
| 92 test() |
