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
|
# Copyright 2001 by Jeffrey Chang. All rights reserved.
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
"""Code to schedule and run multiple processes.
"""
def run(nprocs, fn, fn_args=(), fn_keywds={},
sleep=0.1, always_use_scheduler=0):
"""run(nprocs, fn[, fn_args][, fn_keywds][, sleep])
Run nprocs copies of fn concurrently. The first two parameters of
fn should be a process number (0 to nprocs-1) and the total number
of processes. Additional arguments and keywords can be passed in
the fn_args and fn_keywds parameters. Sleep is the amount of time
the scheduler should wait between process polls.
"""
if nprocs < 1 or nprocs > 100:
raise ValueError, "nprocs %d out of range" % nprocs
# Undocumented: return a list of return values. The return values
# of the functions must be pickle-able types. This is
# undocumented and may go away in future releases. I'm not sure
# it's a good idea right now...
retvals = [None] * nprocs
# If they only want to run 1 process, then just run it without
# going through the scheduler.
if nprocs == 1 and not always_use_scheduler:
args = (0, 1) + fn_args
r = fn(*args, **fn_keywds)
retvals[0] = r
else:
import time
import Scheduler
import Task
def save_retval(task, retvals=retvals):
i = int(task.getName())
retvals[i] = task.retval
scheduler = Scheduler.Scheduler(nprocs, finish_fn=save_retval)
for i in range(nprocs):
args = (i, nprocs) + fn_args
task = Task.Task(name=i, target=fn, args=args, kwargs=fn_keywds)
scheduler.add(task)
while scheduler.run():
time.sleep(sleep)
return retvals
|