def shutdown():
    """Kill subprocesses and wait for them to finish.

    Also dumps output if the main child process fails to exit cleanly.
    """

    # "yarn dev" doesn't pass SIGTERM to its children - to be safe, kill all
    # subprocesses of the child process first
    try:
        # children() returns parent processes first - start with children
        # instead to make killing "yarn dev" more reliable
        for subchild in reversed(child.children(recursive=True)):
            try:
                subchild.terminate()
            except psutil.NoSuchProcess:
                # we may have already caused it to exit by killing its parent
                pass
        child.terminate()
    except psutil.NoSuchProcess:
        # child already exited
        pass

    child.wait()
    if exit_mode == ExitMode.CHILD and child.returncode != 0:
        sys.stdout.buffer.write(child_stdout.to_bytes())
        sys.stdout.flush()
        sys.stderr.write(
            "Subprocess %r exited with error %i:\n"
            % (command, child.returncode)
        )
        sys.stderr.buffer.write(child_stderr.to_bytes())
        sys.stderr.flush()
Kill subprocesses and wait for them to finish.

    Also dumps output if the main child process fails to exit cleanly.
    
fiftyone/service/main.py