(procs, timeout=None, callback=None)
return (list(gone), list(alive))
Convenience function which waits for a list of processes to
    terminate.

    Return a (gone, alive) tuple indicating which processes
    are gone and which ones are still alive.

    The gone ones will have a new 'returncode' attribute indicating
    process exit status (may be None).

    'callback' is a function which gets called every time a process
    terminates (a Process instance is passed as callback argument).

    Function will return as soon as all processes terminate or when
    timeout occurs.

    Typical use case is:

     - send SIGTERM to a list of processes
     - give them some time to terminate
     - send SIGKILL to those ones which are still alive

    Example:

    >>> def on_terminate(proc):
    ...     print("process {} terminated".format(proc))
    ...
    >>> for p in procs:
    ...    p.terminate()
    ...
    >>> gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
    >>> for p in alive:
    ...     p.kill()
Convenience function which waits for a list of processes to
    terminate.
Convenience function which waits for a list of processes to terminate .
def wait_procs(procs, timeout=None, callback=None):
    """Convenience function which waits for a list of processes to
    terminate.

    Return a (gone, alive) tuple indicating which processes
    are gone and which ones are still alive.

    The gone ones will have a new 'returncode' attribute indicating
    process exit status (may be None).

    'callback' is a function which gets called every time a process
    terminates (a Process instance is passed as callback argument).

    Function will return as soon as all processes terminate or when
    timeout occurs.

    Typical use case is:

     - send SIGTERM to a list of processes
     - give them some time to terminate
     - send SIGKILL to those ones which are still alive

    Example:

    >>> def on_terminate(proc):
    ...     print("process {} terminated".format(proc))
    ...
    >>> for p in procs:
    ...    p.terminate()
    ...
    >>> gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
    >>> for p in alive:
    ...     p.kill()
    """
    def check_gone(proc, timeout):
        try:
            returncode = proc.wait(timeout=timeout)
        except TimeoutExpired:
            pass
        else:
            if returncode is not None or not proc.is_running():
                proc.returncode = returncode
                gone.add(proc)
                if callback is not None:
                    callback(proc)

    if timeout is not None and not timeout >= 0:
        msg = "timeout must be a positive integer, got %s" % timeout
        raise ValueError(msg)
    gone = set()
    alive = set(procs)
    if callback is not None and not callable(callback):
        raise TypeError("callback %r is not a callable" % callable)
    if timeout is not None:
        deadline = _timer() + timeout

    while alive:
        if timeout is not None and timeout <= 0:
            break
        for proc in alive:
            # Make sure that every complete iteration (all processes)
            # will last max 1 sec.
            # We do this because we don't want to wait too long on a
            # single process: in case it terminates too late other
            # processes may disappear in the meantime and their PID
            # reused.
            max_timeout = 1.0 / len(alive)
            if timeout is not None:
                timeout = min((deadline - _timer()), max_timeout)
                if timeout <= 0:
                    break
                check_gone(proc, timeout)
            else:
                check_gone(proc, max_timeout)
        alive = alive - gone

    if alive:
        # Last attempt over processes survived so far.
        # timeout == 0 won't make this function wait any further.
        for proc in alive:
            check_gone(proc, 0)
        alive = alive - gone

    return (list(gone), list(alive))
def wait_procs ( procs , timeout = None , callback = None ) : def check_gone ( proc , timeout ) : try : returncode = proc . wait ( timeout = timeout ) except TimeoutExpired : pass else : if returncode is not None or not proc . is_running ( ) : proc . returncode = returncode gone . add ( proc ) if callback is not None : callback ( proc ) if timeout is not None and not timeout >= 0 : msg = "timeout must be a positive integer, got %s" % timeout raise ValueError ( msg ) gone = set ( ) alive = set ( procs ) if callback is not None and not callable ( callback ) : raise TypeError ( "callback %r is not a callable" % callable ) if timeout is not None : deadline = _timer ( ) + timeout while alive : if timeout is not None and timeout <= 0 : break for proc in alive : # Make sure that every complete iteration (all processes) # will last max 1 sec. # We do this because we don't want to wait too long on a # single process: in case it terminates too late other # processes may disappear in the meantime and their PID # reused. max_timeout = 1.0 / len ( alive ) if timeout is not None : timeout = min ( ( deadline - _timer ( ) ) , max_timeout ) if timeout <= 0 : break check_gone ( proc , timeout ) else : check_gone ( proc , max_timeout ) alive = alive - gone if alive : # Last attempt over processes survived so far. # timeout == 0 won't make this function wait any further. for proc in alive : check_gone ( proc , 0 ) alive = alive - gone return ( list ( gone ) , list ( alive ) )