| # Very rudimentary test of thread module | 
 |  | 
 | # Create a bunch of threads, let each do some work, wait until all are done | 
 |  | 
 | from test_support import verbose | 
 | import random | 
 | import thread | 
 | import time | 
 |  | 
 | mutex = thread.allocate_lock() | 
 | rmutex = thread.allocate_lock() # for calls to random | 
 | running = 0 | 
 | done = thread.allocate_lock() | 
 | done.acquire() | 
 |  | 
 | numtasks = 10 | 
 |  | 
 | def task(ident): | 
 | 	global running | 
 | 	rmutex.acquire() | 
 | 	delay = random.random() * numtasks | 
 | 	rmutex.release() | 
 | 	if verbose: | 
 | 	    print 'task', ident, 'will run for', round(delay, 1), 'sec' | 
 | 	time.sleep(delay) | 
 | 	if verbose: | 
 | 	    print 'task', ident, 'done' | 
 | 	mutex.acquire() | 
 | 	running = running - 1 | 
 | 	if running == 0: | 
 | 		done.release() | 
 | 	mutex.release() | 
 |  | 
 | next_ident = 0 | 
 | def newtask(): | 
 | 	global next_ident, running | 
 | 	mutex.acquire() | 
 | 	next_ident = next_ident + 1 | 
 | 	if verbose: | 
 | 	    print 'creating task', next_ident | 
 | 	thread.start_new_thread(task, (next_ident,)) | 
 | 	running = running + 1 | 
 | 	mutex.release() | 
 |  | 
 | for i in range(numtasks): | 
 | 	newtask() | 
 |  | 
 | print 'waiting for all tasks to complete' | 
 | done.acquire() | 
 | print 'all tasks done' | 
 |  | 
 | class barrier: | 
 | 	def __init__(self, n): | 
 | 		self.n = n | 
 | 		self.waiting = 0 | 
 | 		self.checkin  = thread.allocate_lock() | 
 | 		self.checkout = thread.allocate_lock() | 
 | 		self.checkout.acquire() | 
 |  | 
 | 	def enter(self): | 
 | 		checkin, checkout = self.checkin, self.checkout | 
 |  | 
 | 		checkin.acquire() | 
 | 		self.waiting = self.waiting + 1 | 
 | 		if self.waiting == self.n: | 
 | 			self.waiting = self.n - 1 | 
 | 			checkout.release() | 
 | 			return | 
 | 		checkin.release() | 
 |  | 
 | 		checkout.acquire() | 
 | 		self.waiting = self.waiting - 1 | 
 | 		if self.waiting == 0: | 
 | 			checkin.release() | 
 | 			return | 
 | 		checkout.release() | 
 |  | 
 | numtrips = 3 | 
 | def task2(ident): | 
 | 	global running | 
 | 	for i in range(numtrips): | 
 | 		if ident == 0: | 
 | 			# give it a good chance to enter the next | 
 | 			# barrier before the others are all out | 
 | 			# of the current one | 
 | 			delay = 0.001 | 
 | 		else: | 
 | 			rmutex.acquire() | 
 | 			delay = random.random() * numtasks | 
 | 			rmutex.release() | 
 | 		if verbose: | 
 | 		    print 'task', ident, 'will run for', round(delay, 1), 'sec' | 
 | 		time.sleep(delay) | 
 | 		if verbose: | 
 | 		    print 'task', ident, 'entering barrier', i | 
 | 		bar.enter() | 
 | 		if verbose: | 
 | 		    print 'task', ident, 'leaving barrier', i | 
 | 	mutex.acquire() | 
 | 	running = running - 1 | 
 | 	if running == 0: | 
 | 		done.release() | 
 | 	mutex.release() | 
 |  | 
 | print '\n*** Barrier Test ***' | 
 | if done.acquire(0): | 
 | 	raise ValueError, "'done' should have remained acquired" | 
 | bar = barrier(numtasks) | 
 | running = numtasks | 
 | for i in range(numtasks): | 
 | 	thread.start_new_thread(task2, (i,)) | 
 | done.acquire() | 
 | print 'all tasks done' |