나에게 이것은 실제로 매우 간단합니다.
서브 프로세스 옵션 :
subprocess
입니다 다른 실행 파일을 실행하는 것이 주위에 기본적으로 래퍼 --- os.fork()
및 os.execve()
옵션 배관에 대한 일부 지원 (에와 하위 프로세스에서 파이프를 설정. 분명히 그럴 수있어 다른 프로세스 간 통신 (IPC)와 같은 소켓 같은 메커니즘, 또는 POSIX 또는 SysV 공유 메모리하지만 호출하는 프로그램에서 지원하는 인터페이스와 IPC 채널로 제한됩니다.
일반적으로 누군가는 subprocess
동기식으로 --- 단순히 외부 유틸리티를 호출하고 출력을 다시 읽거나 완료를 기다립니다 (임시 파일에서 결과를 읽거나 데이터베이스에 게시 한 후).
그러나 수백 개의 하위 프로세스를 생성하고 폴링 할 수 있습니다. 내가 개인적으로 가장 좋아하는 유틸리티 클래스 는 정확히 그렇게합니다.
모듈 의 가장 큰 단점 은 subprocess
I / O 지원이 일반적으로 차단된다는 것입니다. 일부 향후 버전의 Python 3.x 및 대체 asyncproc (모든 종류의 문서 나 README가 아닌 다운로드로 연결되는 경고) 에서이를 수정 하는 초안 PEP-3145 가 있습니다. 또한 PIPE 파일 디스크립터를 직접 가져 오고 조작 하는 것이 비교적 쉽다는 것을 발견했습니다. 비록 이것이 비 UNIX 플랫폼에 이식 가능한지 모르겠지만.fcntl
Popen
(업데이트 : 2019 년 8 월 7 일 : ayncio 하위 프로세스에 대한 Python 3 지원 : asyncio 하위 프로세스 )
subprocess
이벤트 핸들링 지원이 거의 없습니다 ... 모듈과 평범한 구식 UNIX / Linux 신호를 사용할 수 있지만signal
--- 프로세스를 부드럽게 종료합니다.
멀티 프로세싱 옵션 :
multiprocessing
이 프로세스 제품군 간의보다 유연한 통신을 지원 하는 기존 (Python) 코드 내에서 함수를 실행 하기위한 것입니다. 특히 가능한 multiprocessing
경우 모듈의 Queue
객체를 중심으로 IPC 를 구축하는 것이 가장 좋지만 Event
객체 및 다양한 기타 기능을 사용할 수도 있습니다 (일부는 mmap
지원이 충분한 플랫폼에서 지원을 기반으로 구축 된 것 같습니다 ).
Python의 multiprocessing
모듈은 CPython이 GIL (Global Interpreter Lock)에도 불구하고 여러 CPU / 코어 사이에서 처리를 확장 할 수 있도록 허용하면서 매우 유사한 인터페이스 및 기능을 제공하기위한 것 threading
입니다. OS 커널 개발자가 수행 한 모든 세분화 된 SMP 잠금 및 일관성 노력을 활용합니다.
스레딩 옵션 :
threading
I / O 바운드 (여러 CPU 코어에 걸쳐 확장 할 필요가 없음)이고 스레드 스위칭 (공유 코어 메모리 사용) 대 프로세스 /의 매우 낮은 대기 시간 및 스위칭 오버 헤드의 이점 이 있는 상당히 좁은 범위의 애플리케이션을위한 것입니다. 컨텍스트 전환. Linux에서 이것은 거의 빈 집합입니다 (Linux 프로세스 전환 시간은 스레드 스위치에 매우 가깝습니다).
threading
앓고 파이썬에서 두 가지 주요 단점 .
물론 하나는 특정 구현입니다. --- 대부분 CPython에 영향을 미칩니다. 그것이 GIL입니다. 대부분의 경우 대부분의 CPython 프로그램은 두 개 이상의 CPU (코어) 가용성의 이점을 얻지 못하며 종종 GIL 잠금 경합으로 인해 성능이 저하 됩니다.
구현과 관련이없는 더 큰 문제는 스레드가 동일한 메모리, 신호 처리기, 파일 설명자 및 특정 기타 OS 리소스를 공유한다는 것입니다. 따라서 프로그래머는 개체 잠금, 예외 처리 및 전체 프로세스 (스레드 모음)를 종료, 중단 또는 교착 상태로 만들 수있는 코드의 기타 측면에 대해 매우주의해야합니다.
비교해 보면 multiprocessing
모델은 각 프로세스에 자체 메모리, 파일 설명자 등을 제공합니다. 그중 하나에서 충돌 또는 처리되지 않은 예외는 해당 리소스 만 죽이고 자식 또는 형제 프로세스의 사라짐을 강력하게 처리하는 것이 디버깅, 격리보다 훨씬 쉬울 수 있습니다. 스레드에서 유사한 문제를 수정하거나 해결합니다.
- (참고 : NumPy
threading
와 같은 주요 Python 시스템과 함께 사용하면 대부분의 Python 코드보다 GIL 경합으로 인한 피해가 훨씬 적을 수 있습니다. 그 이유는 NumPy의 네이티브 / 바이너리 부분, 예를 들어 안전 할 때 GIL을 해제합니다.)
트위스트 옵션 :
Twisted 가 우아하고 이해하기 매우 어려운 또 다른 대안을 제공 한다는 점도 주목할 가치가 있습니다. 기본적으로 Twisted 팬이 갈퀴와 횃불로 우리 집을 휩쓸 수있을 정도로 지나치게 단순화 할 위험이있는 Twisted는 모든 (단일) 프로세스 내에서 이벤트 중심의 협동 멀티 태스킹을 제공합니다.
이것이 어떻게 가능한지 이해하려면 select()
( select () 또는 poll () 또는 유사한 OS 시스템 호출을 중심으로 구축 될 수있는) 의 기능에 대해 읽어야 합니다. 기본적으로 파일 설명자 목록 또는 일부 시간 초과에 대한 활동을 보류하기 위해 OS가 절전 모드를 요청하는 기능에 의해 구동됩니다.
이러한 각 호출에서 깨어나 select()
는 것은 이벤트입니다. 일부 수의 소켓 또는 파일 설명자에서 사용 가능한 (읽을 수있는) 입력이 포함되거나 다른 (쓰기 가능한) 설명자 또는 소켓에서 사용 가능한 버퍼링 공간, 일부 예외적 인 조건 (TCP 예를 들어 대역 외 PUSH 패킷) 또는 TIMEOUT.
따라서 Twisted 프로그래밍 모델은 이러한 이벤트를 처리 한 다음 결과 "주"처리기를 반복하여 이벤트를 처리기에 전달할 수 있도록 구축되었습니다.
저는 개인적으로 프로그래밍 모델을 연상시키는 Twisted 라는 이름을 생각 합니다. 문제에 대한 접근 방식은 어떤 의미에서는 내부가 "뒤틀려"있어야하기 때문입니다. 프로그램을 입력 데이터 및 출력 또는 결과에 대한 일련의 작업으로 생각하는 대신 프로그램을 서비스 또는 데몬으로 작성하고 다양한 이벤트에 반응하는 방식을 정의합니다. (사실 Twisted 프로그램의 핵심 "주 루프"는 (보통? 항상?) a reactor()
)입니다.
Twisted 사용에 대한 주요 과제 는 이벤트 중심 모델에 대한 마음을 비틀고 Twisted 프레임 워크 내에서 협력하도록 작성되지 않은 클래스 라이브러리 또는 툴킷의 사용을 피하는 것입니다. 이것이 Twisted가 SSH 프로토콜 처리, curses 및 자체 하위 프로세스 / Popen 함수를위한 자체 모듈과 처음에는 Python 표준 라이브러리에서 중복되는 것처럼 보이는 다른 많은 모듈 및 프로토콜 핸들러를 제공하는 이유입니다.
Twisted를 사용하지 않더라도 개념적 수준에서 이해하는 것이 유용하다고 생각합니다. 스레딩, 다중 처리 및 하위 프로세스 처리 및 수행하는 분산 처리의 성능, 경합 및 이벤트 처리에 대한 통찰력을 제공 할 수 있습니다.
( 참고 : Python 3.x의 최신 버전에는 async def , @ async.coroutine 데코레이터 및 await 키워드 와 같은 asyncio (비동기 I / O) 기능이 포함되어 있으며 향후 지원 에서 산출됩니다 .이 모든 기능은 다음과 거의 유사합니다. 트위스트 과정 (협동 멀티 태스킹) 관점)에서. (Python 3에 대한 Twisted 지원의 현재 상태는 https://twistedmatrix.com/documents/current/core/howto/python3.html )
배포 옵션 :
아직 묻지 않았지만 고려할 가치가있는 또 다른 처리 영역은 분산 처리입니다. 분산 처리 및 병렬 계산을위한 많은 Python 도구와 프레임 워크가 있습니다. 개인적으로 가장 사용하기 쉬운 것은 그 공간에있는 것으로 가장 적게 간주되는 것입니다.
Redis를 중심으로 분산 처리를 구축하는 것은 거의 간단합니다 . 전체 키 저장소는 작업 단위 및 결과를 저장하는 데 사용될 수 있으며, Redis LIST는 Queue()
유사한 객체 로 사용될 수 있으며 , PUB / SUB 지원은 Event
유사한 처리에 사용될 수 있습니다 . 느슨한 Redis 인스턴스 클러스터에 복제 된 키를 해시하고 값을 사용하여 토폴로지 및 해시 토큰 매핑을 저장하여 작업자를 조정하기 위해 단일 인스턴스의 용량 이상으로 확장하기위한 일관된 해싱 및 장애 조치를 제공 할 수 있습니다. 그리고 그들 사이에서 데이터 (pickled, JSON, BSON 또는 YAML)를 마샬링합니다.
물론 Redis를 중심으로 더 크고 정교한 솔루션을 구축하기 시작하면 Celery , Apache Spark 및 Hadoop , Zookeeper , etcd , Cassandra 등을 사용하여 이미 해결 된 많은 기능을 다시 구현 하게됩니다. 이들 모두는 서비스에 대한 Python 액세스를위한 모듈을 가지고 있습니다.
[업데이트 : 분산 시스템 전반에 걸쳐 계산 집약적 인 Python을 고려하는 경우 고려해야 할 몇 가지 리소스 : IPython Parallel 및 PySpark . 이들은 범용 분산 컴퓨팅 시스템이지만 특히 액세스 가능하고 인기있는 하위 시스템 데이터 과학 및 분석입니다].
결론
단일 스레드에서 하위 프로세스에 대한 간단한 동기 호출, 폴링 된 하위 프로세스 풀, 스레드 및 다중 처리, 이벤트 기반 공동 작업 멀티 태스킹, 분산 처리에 이르기까지 Python을위한 처리 대안의 범위가 있습니다.