Tornado의 다중 프로세스 관리 분석

3366 단어 tornado
Tornado의 HTTPServer는 단일 프로세스 단일 스레드 모드이며 다중 프로세스 서버를 만드는 인터페이스를 제공합니다. 구체적인 구현은 메인 프로세스가 HTTPServer를 시작할 때process를 통해입니다.fork_프로세스 (num_processes) 는 모든 프로세스 간에 포트를 공유하는 새로운 서버 하위 프로세스를 생성합니다.Tornado의 다중 프로세스 관리는 프로세스를 참조할 수 있습니다.이 파일.
    global _task_id
    assert _task_id is None
    if num_processes is None or num_processes <= 0:
        num_processes = cpu_count()
    gen_log.info("Starting %d processes", num_processes)
    children = {}
    
def cpu_count() -> int:
    """Returns the number of processors on this machine."""
    if multiprocessing is None:
        return 1
    try:
        return multiprocessing.cpu_count()
    except NotImplementedError:
        pass
    try:
        return os.sysconf("SC_NPROCESSORS_CONF")  # type: ignore
    except (AttributeError, ValueError):
        pass
    gen_log.error("Could not detect number of processors; assuming 1")
    return 1

프로세스 수나 프로세스 수가 <=0이 없을 때, 기본적으로 cpu 수를 생성할 프로세스 수로 사용합니다.
    def start_child(i: int) -> Optional[int]:
        pid = os.fork()
        if pid == 0:
            # child process
            _reseed_random()
            global _task_id
            _task_id = i
            return i
        else:
            children[pid] = i
            return None

이것은 내부 함수이며, 작용은 바로 하위 프로세스를 생성하는 것이다.그것은 동시에 두 가지 상태를 되돌려준다,os.fork () 는 하위 프로세스를 만들었습니다. 하위 프로세스가 성공하면 하위 프로세스pid를 되돌려줍니다.하위 프로세스 자체가 성공적으로 만들어져서 자신의 상태 코드를 0으로 되돌려줍니다.pid==0은 cpu가 하위 프로세스로 전환되었음을 나타내고,else는 부모 프로세스에서 작업하고 있음을 나타냅니다.
  for i in range(num_processes):
        id = start_child(i)
        if id is not None:
            return id

if id is not None은 우리가 방금 생성한 하위 프로세스의 상하문에 있다면 아무것도 하지 않고 하위 프로세스의 작업 id를 되돌려주면 된다고 표시합니다.상위 프로세스의 상하문에 있으면 하위 프로세스를 계속 생성합니다.
 num_restarts = 0
    while children:
        pid, status = os.wait()
        if pid not in children:
            continue
        id = children.pop(pid)
        if os.WIFSIGNALED(status):
            gen_log.warning(
                "child %d (pid %d) killed by signal %d, restarting",
                id,
                pid,
                os.WTERMSIG(status),
            )
        elif os.WEXITSTATUS(status) != 0:
            gen_log.warning(
                "child %d (pid %d) exited with status %d, restarting",
                id,
                pid,
                os.WEXITSTATUS(status),
            )
        else:
            gen_log.info("child %d (pid %d) exited normally", id, pid)
            continue
        num_restarts += 1
        if num_restarts > max_restarts:
            raise RuntimeError("Too many child restarts, giving up")
        new_id = start_child(id)
        if new_id is not None:
            return new_id

위의 이 코드는 모두 부모 프로세스에서 진행된 것이다.pid, status = os.wait () 는 임의의 하위 프로세스가 종료되거나 끝날 때까지 기다린다는 뜻입니다. 이 때 우리children 테이블에서 제거한 다음status를 통해 하위 프로세스가 종료되는 원인을 판단합니다.과일 프로세스는kill 신호를 받거나 exception을 던졌기 때문에 하위 프로세스를 다시 시작합니다. 물론 방금 종료한 하위 프로세스의 작업 번호를 사용합니다.만약 하위 프로세스가 스스로 일을 끝내고 물러난다면, 그만두고 다른 하위 프로세스가 물러날 때까지 기다리세요.
if new_id is not None:

    return new_id


주로 하위 프로세스를 종료하는 공간입니다. 부모 프로세스에서만 남은 일을 합니다. 그렇지 않으면 아까 아버지 프로세스의 코드가 하위 프로세스에서도 똑같이 실행되고 무한 순환이 이루어집니다.

좋은 웹페이지 즐겨찾기