From: epg <> Date: Wed, 26 Jul 2006 21:29:07 +0000 (+0000) Subject: Add Python implemention of Jobs package. X-Git-Url: https://diplodocus.org/git/flac-archive/commitdiff_plain/89a0dc2fafc1aabfa87b075e0e58babb03ed86dd Add Python implemention of Jobs package. --- diff --git a/jobs.py b/jobs.py new file mode 100644 index 0000000..5ce62b9 --- /dev/null +++ b/jobs.py @@ -0,0 +1,58 @@ +import os, sys + +from errno import ECHILD, EINTR + +from org.diplodocus.util import nothing + +def newjob(f, jobs, debug): + if not debug: + pid = os.fork() + + if debug or pid == 0: + sys.exit(f()) + + jobs.append(pid) + + return pid + +def run(get_job, maxjobs=1, notify_start=nothing, notify_finish=nothing, + debug=False): + jobs = [] + + while True: + if len(jobs) < maxjobs: + while True: + job = get_job() + if job == None: + break + pid = newjob(job, jobs, debug) + notify_start(pid, jobs) + if len(jobs) == maxjobs: + break + + # No jobs running and get-job returned undef; we're finished. + if len(jobs) == 0 and job == None: + return + + # Now running as many jobs as we can, block waiting for one to die. + while True: + try: + (pid, status) = os.waitpid(-1, 0) + except EnvironmentError, error: + if error.errno != ECHILD and error.errno != EINTR: + raise + if pid > 0: + break + + # Handle the finished job, and see if others have finished. + while True: + jobs.remove(pid) + notify_finish(pid, status, jobs) + try: + (pid, status) = os.waitpid(-1, os.WNOHANG) + except EnvironmentError, error: + if error.errno != ECHILD and error.errno != EINTR: + raise + break + if pid == 0: + break diff --git a/jobtest.py b/jobtest.py new file mode 100644 index 0000000..23034d2 --- /dev/null +++ b/jobtest.py @@ -0,0 +1,16 @@ +import os +import sys +import jobs + +work = range(17) + +def getjob(): + try: + job = work.pop() + except IndexError: + return None + return lambda: sys.stdout.write('%d %d\n' % (os.getpid(), job)) + +jobs.run(get_job=getjob, maxjobs=8, + notify_start=lambda pid, jobs: sys.stdout.write('%d %d jobs\n' % (pid, len(jobs))), + notify_finish=lambda pid, status, jobs: sys.stdout.write('%d %d %d jobs\n' % (pid, status, len(jobs))))