Commits

Anonymous committed 301f8ca

Initial revision

  • Participants
  • Parent commits 33d3344
  • Branches legacy-trunk

Comments (0)

Files changed (1)

Demo/threads/Generator.py

+# 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()