Python threading tutorial?

Gerrit Holl gerrit at nl.linux.org
Sun Jan 5 10:03:38 CET 2003


Dennis Lee Bieber schreef op zondag  5 januari om 01:30:38 +0000:
> > My case is an exercise application in which multiple object are
> > randomly wandering through a field, but when they meet they interact
> > and go in opposite directions. All those objects will be class
> > instances and need to "live" seperately, only interacting when they
> > meet. Can threads help me in this particular problem, or do threads
> > have (very) different uses?
> >
>         While you could make each such object a separate thread, each such 
> object would then have to broadcast its location to all other threads 
> so they, in turn, can determine if their next move puts them into 
> collision.

I have currently implemented it like this: each object is a instance of
the class Person, and has a location in the Matrix instance mx; they are
all in the _same_ instance, so when an object tries to 'go north', it can
check whether there already is a Person instance there or not, so...

> On collision, that thread would have to message the other 
> thread to do the interaction. Sounds like an awful lot of message 
> Queues (see Queue.Queue) and maybe synchronization primitives (see 
> threading.Semaphore, threading.Event, threading.Condition).

...so I am currently not using the queues. Does that mean my application
is not reliable, or is this a reliable solution? It seems to run ok...

My source code:
#!/usr/bin/python

import random
import threading
import time

class Collision(Exception): pass

class Matrix(list):
	"""Two-dimensional Matrix"""
	def __init__(self, x, y, bg=''):
		"""Matrix(x, y, bg='')
			2-dimensional matrix of x * y filled with bg
		"""
		self.x = x
		self.y = y
		self.bg = bg
		L=[]
		[self.append([bg]*x) for i in xrange(y)]

class Person(threading.Thread):

	def __init__(self, mx, name):
		"""Person(mx, name):
			mx:	2-dimensional matrix
			name: persons name
		"""
		threading.Thread.__init__(self)
		self.mx = mx
		self.name = name
		self.x = random.randint(0, mx.x-1)
		self.y = random.randint(0, mx.y-1)
		if not isinstance(self.mx[self.x][self.y], self.__class__):
			self.mx[self.x][self.y] = self
		else:
			self.__init__(mx, self.name)

	def __repr__(self):
		return self.name

	def move(self, dir):
		newx = self.x
		newy = self.y
		for d in dir:
			if d == 'n':
				newy += 1
			elif d == 's':
				newy -= 1
			elif d == 'e':
				newx -= 1
			elif d == 'w':
				newx += 1
			else:
				raise TypeError, "argument must be sequence of n, s, e, w"

		if not 0 <= newx < self.mx.x:
			raise IndexError
		if not 0 <= newy < self.mx.y:
			raise IndexError

		if isinstance(self.mx[newx][newy], self.__class__):
			raise Collision

		self.mx[self.x][self.y] = self.mx.bg
		self.mx[newx][newy] = self
		self.x = newx
		self.y = newy


	def run(self):
		while 1:
			time.sleep(random.random() * 2)
			try:
				self.move(random.choice('nsew') + random.choice('nsew'))
			except (Collision, IndexError):
				pass

def test():
	from time import sleep
	from pprint import PrettyPrinter
	p = PrettyPrinter(width=200)
	mx = Matrix(20, 20)
	mensen = []
	namen = ["Brian", "Reg", "Jailer", "Geoffrey", "Stan", "Warris",
		"Mandy", "Colin", "Francis", "Ben", "Eddie"]
	for naam in namen:
		mensen.append(Person(mx, naam))
		mensen[-1].start()
	while 1:
		time.sleep(.5)
		print "\x1b[H\x1b[2J"
		p.pprint(list(mx))
		

if __name__ == '__main__':
	test()


yours,
Gerrit.

-- 
Asperger Syndroom - een persoonlijke benadering:
	http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
	http://www.sp.nl/





More information about the Python-list mailing list