4 from Queue import Queue
6 def ThreadedMethod(callable, results, errors):
8 A function decorator that returns a running thread. The thread
9 runs the specified callable and stores the result in the specified
12 def wrapper(args, kwds):
13 class ThreadInstance(threading.Thread):
16 results.put(callable(*args, **kwds))
18 errors.put(traceback.format_exc())
20 thread = ThreadInstance()
29 ThreadManager executes a callable in a thread and stores the result
30 in a thread safe queue.
36 def run (self, method, *args, **kwds):
38 Execute a callable in a separate thread.
40 method = ThreadedMethod(method, self.results, self.errors)
41 thread = method(args, kwds)
42 self.threads.append(thread)
48 Wait for all threads to complete
50 for thread in self.threads:
53 def get_results(self):
55 Return a list of all the results so far. Blocks until
56 all threads are finished.
60 while not self.results.empty():
61 results.append(self.results.get())
66 Return a list of all errors. Blocks untill all threads are finished
70 while not self.errors.empty():
71 errors.append(self.errors.get())
75 if __name__ == '__main__':
77 def f(name, n, sleep=1):
79 for i in range(n, n+5):
80 print "%s: %s" % (name, i)
84 def e(name, n, sleep=1):
86 for i in range(n, n+3) + ['n', 'b']:
87 print "%s: 1 + %s:" % (name, i)
92 threads = ThreadManager()
93 threads.run(f, "Thread1", 10, 2)
94 threads.run(f, "Thread2", -10, 1)
95 threads.run(e, "Thread3", 19, 1)
97 results = threads.get_results()
98 errors = threads.get_errors()
99 print "Results:", results
100 print "Errors:", errors