home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / threads / Generator.py < prev    next >
Text File  |  1994-05-03  |  2KB  |  85 lines

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