다중 처리 fork () 대 spawn ()

Sep 28 2020

나는 파이썬 문서 에서 두 가지에 대한 설명을 읽고 있었다 .

알

부모 프로세스는 새로운 파이썬 인터프리터 프로세스를 시작합니다. 자식 프로세스는 프로세스 개체 run () 메서드를 실행하는 데 필요한 리소스 만 상속합니다. 특히 부모 프로세스의 불필요한 파일 설명자 및 핸들은 상속되지 않습니다. 이 방법을 사용하여 프로세스를 시작하는 것은 fork 또는 forkserver를 사용하는 것에 비해 다소 느립니다. [Unix 및 Windows에서 사용 가능합니다. Windows 및 macOS의 기본값입니다.]

포크

부모 프로세스는 os.fork ()를 사용하여 Python 인터프리터를 포크합니다. 시작될 때 자식 프로세스는 부모 프로세스와 사실상 동일합니다. 부모의 모든 리소스는 자식 프로세스에 상속됩니다. 다중 스레드 프로세스를 안전하게 분기하는 것은 문제가 있습니다. [Unix에서만 사용 가능합니다. Unix의 기본값.]

그리고 내 질문은 :

  1. 복사 할 리소스를 식별하려고하지 않기 때문에 포크가 훨씬 더 빠르나요?
  2. 포크가 모든 것을 복제하기 때문에 spawn ()에 비해 훨씬 더 많은 리소스를 "낭비"하는 것입니까?

답변

3 Darkonaut Sep 28 2020 at 12:25
  1. 복사 할 리소스를 식별하려고하지 않기 때문에 포크가 훨씬 더 빠르나요?

예, 훨씬 빠릅니다. 커널은 전체 프로세스를 복제 할 수 있습니다 만 사본을 수정 메모리 페이지를 전체 . 리소스를 새 프로세스에 연결하고 인터프리터를 처음부터 부팅 할 필요가 없습니다.

  1. 포크가 모든 것을 복제하기 때문에 spawn ()에 비해 훨씬 더 많은 리소스를 "낭비"하는 것입니까?

최신 커널의 포크는 "기록시 복사" 만 수행하며 실제로 변경되는 메모리 페이지에만 영향을줍니다. 주의 할 점은 "쓰기"는 이미 CPython의 개체에 대한 반복 만 포함한다는 것입니다. 객체에 대한 참조 횟수가 증가하기 때문입니다.

사용중인 작은 개체가 많은 장기 실행 프로세스가있는 경우 스폰보다 더 많은 메모리를 낭비 할 수 있습니다. 일화 적으로 나는 페이스 북이 파이썬 프로세스를 위해 "포크"에서 "스폰"으로 전환하면서 메모리 사용량을 상당히 줄 였다고 주장했던 것을 기억합니다.