On Fri, 20 Jan 2006, Bernard Lebel wrote:
> So have written a little test script. The fact is that I want to be able > to manage the same queue from separate threads. Below is an example of > what my real program is doing: Hi Bernard, One problem is that there's a single outputQueue being presented to get results back from the Server. A different approach is to use a lot of outputQueues. *grin* The idea is that when we send a job submission, we immediately get back a "ticket". We can then use this ticket to claim() our result. Each ticket is unique to a job submission, so we shouldn't see any bleeding going on between clients. Here's some code that implements this idea. It's a little complex, so you may want to read through it slowly: ################################################ from threading import Thread from Queue import Queue class Ticket: """A small token that we can use to claim our result.""" def __init__(self, q): self.q = q self.result = None self.done = False def claim(self): if not self.done: self.result = self.q.get() self.done = True return self.result class Server: _QUIT_JOB = ['Quit!'] def __init__(self): """A queue will contain 2-tuples of (job, outputQueue) elements.""" self.queue = Queue() def startServer(self): """Brings the server online.""" Thread(target=self._jobLoop).start() def schedule(self, job): """Schedules a job to be done and returns a ticket that the client can use later to claim the result of the job.""" outputQueue = Queue() self.queue.put((job, outputQueue)) return Ticket(outputQueue) def scheduleShutdown(self): """Add a 'job' that shuts the system down.""" self.queue.put((Server._QUIT_JOB, None)) def _jobLoop(self): """Continue looping through tasks.""" while True: print "Looping..." (nextJob, outputQueue) = self.queue.get() if nextJob is Server._QUIT_JOB: return returnValue = self._doJob(nextJob) outputQueue.put(returnValue) def _doJob(self, job): print "I'm doing", job return job + job ## something to show that we're doing something def separateCaller(server): for i in range(1000, 1004 + 1): print "--Separate caller asks %d" % i ticket = server.schedule(str(i)) print "--Separate caller got %s" % ticket.claim() if __name__ == '__main__': server = Server() server.startServer() Thread(target=separateCaller, args=(server,)).start() result1 = server.schedule("1") print "result1: %s" % result1.claim() result2 = server.schedule("2") print "result2: %s" % result2.claim() result3 = server.schedule("3") print "result3: %s" % result3.claim() server.scheduleShutdown() ############################################################# Play around with this a bit and see if it makes sense to you. You might also be interested in the amusing article "Starbucks Does Not Use Two-Phase Commit": http://www.eaipatterns.com/ramblings/18_starbucks.html as it touches on concepts in the code. If you have more questions, please feel free to ask! _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor