'This takes in a dictionary of functions which map to a set of
functions that they depend on.
functions: This is either a list of or dictionary of functions to
be run.  If it\'s a dictionary, the value should be a set
of other functions this function is dependent on.  If its
a list (or tuple or anything iterable that returns a
single element each iteration), then it\'s assumed that
there are no dependencies.
max_simultaneous_procs: Throttle the number of processes we have
running at once.'

def __init__(self, functions, max_simultaneous_procs=20):

    if (not isinstance(functions, dict)):
        function_list = functions
        functions = {}
        for fn in function_list:
            functions[fn] = set()
    dependents = {}
    for (fn, deps) in functions.iteritems():
        dependents[fn] = []
    for (fn, deps) in functions.iteritems():
        for dep in deps:
            dependents[dep].append(fn)
    self.max_procs = max_simultaneous_procs
    self.functions = functions
    self.dependents = dependents
    self.pid_map = {}
    self.ready_to_run = []
