cinap_lenrekadd hg and python4bb9e2215 years agoHistory
84 lines · 2.4 KB · Python
RawDownload
# 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()