Scheduler.py

00001"""Simple scheduling of threads to be run.Classes:Scheduler Schedules threads to be run."""00008class Scheduler:
"""Schedules threads to be run. No prioritization. Nothing fancy. Methods: add Add a thread to be run. num_left Return the number of threads left. num_running Return the number of threads currently running. run Main loop. Returns whether there's still threads left. """00018def __init__(self, max_threads, start_fn=None, finish_fn=None):
"""Scheduler(max_threads[, start_fn][, finish_fn]) -> object max_threads is the maximum number of threads to run at a time. start_fn and finish_fn are optional callbacks that take a thread as an argument. They are called before and after each thread. """if max_threads <= 0:
raise ValueError, "You must specify a positive number of threads!"
self._max_threads = max_threads # maximum active threads at a time
self._start_fn = start_fn # called before a thread starts
self._finish_fn = finish_fn # called when a thread is finished
self._waiting = [] # list of threads waiting to run
self._in_progress = [] # list of threads running00035def run(self):
"""S.run() -> boolean Execute the main loop. Return a boolean indicating whether threads are still running. """# See if the running threads are finished. Remove any that# are.
i=0
while i < len(self._in_progress):
ifnot self._in_progress[i].isAlive():
t = self._in_progress.pop(i)
if self._finish_fn:
self._finish_fn(t)
else:
i = i + 1
# If I have any more slots, start new threads.while self._waitingand len(self._in_progress) < self._max_threads:
t = self._waiting.pop(0)
if self._start_fn:
self._start_fn(t)
t.start()
self._in_progress.append(t)
return self._waitingor self._in_progress00063def add(self, thread):
"""S.add(thread)"""
self._waiting.append(thread)
00067def num_left(self):
"""S.num_left() -> number of threads left to run"""return len(self._waiting)
00071def num_running(self):
"""S.num_running() -> number of threads currently running"""return len(self._in_progress)