1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
"""
Simple scheduling of threads to be run.
Classes:
Scheduler Schedules threads to be run.
"""
class 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.
"""
def __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 running
def 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):
if not 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._waiting and 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._waiting or self._in_progress
def add(self, thread):
"""S.add(thread)"""
self._waiting.append(thread)
def num_left(self):
"""S.num_left() -> number of threads left to run"""
return len(self._waiting)
def num_running(self):
"""S.num_running() -> number of threads currently running"""
return len(self._in_progress)
|