programing

Python에서 하위 프로세스, 멀티프로세싱 및 스레드 중에서 결정하시겠습니까?

newstyles 2023. 8. 12. 10:04

Python에서 하위 프로세스, 멀티프로세싱 및 스레드 중에서 결정하시겠습니까?

나는 파이썬 프로그램을 병렬화해서 그것이 실행되는 컴퓨터에서 여러 개의 프로세서를 사용할 수 있게 하고 싶습니다.프로그램의 모든 병렬 "스레드"가 독립적이고 출력을 별도의 파일에 기록한다는 점에서 병렬화는 매우 간단합니다.정보 교환을 위해 스레드가 필요하지는 않지만, 제 파이프라인의 일부 단계는 출력에 따라 다르기 때문에 스레드가 언제 완료되는지 알아야 합니다.

Mac, Linux 및 Windows에서 모든 Python 버전에서 실행할 수 있도록 하려면 휴대성이 중요합니다.이러한 제약 조건을 고려할 때, 이를 구현하는 데 가장 적합한 파이썬 모듈은 무엇입니까?스레드, 서브프로세스, 멀티프로세싱 중 하나를 결정하려고 하는데, 관련 기능을 모두 제공하는 것 같습니다.

이것에 대한 의견이 있습니까?저는 휴대가 가능한 가장 간단한 해결책을 원합니다.

저에게 이것은 사실 매우 간단합니다.

하위 프로세스 옵션:

subprocess다른 실행 파일을 실행하기 위한 것입니다. 기본적으로 래퍼입니다.os.fork()그리고.os.execve()선택적 배관(하위 프로세스에 대한 파이프 설정)을 일부 지원합니다.소켓이나 Posix 또는 SysV 공유 메모리와 같은 다른 프로세스 간 통신(IPC) 메커니즘을 사용할 수 있습니다.그러나 호출 중인 프로그램에서 지원하는 인터페이스와 IPC 채널로 제한됩니다.

일반적으로 다음 중 하나를 사용합니다.subprocesssynchronously --- 일부 외부 유틸리티를 호출하여 출력을 다시 읽거나 완료되기를 기다리는 것입니다(임시 파일에서 결과를 읽거나 일부 데이터베이스에 게시한 후).

그러나 수백 개의 하위 프로세스를 생성하고 이를 폴링할 수 있습니다.제가 개인적으로 가장 좋아하는 유틸리티 클래스가 바로 그것을 합니다.가장단점은subprocess모듈은 I/O 지원이 일반적으로 차단된다는 것입니다.PEP-3145는 Python 3.x의 미래 버전에서 이 문제를 해결하기 위한 초안과 다른 비동기식(어떤 종류의 문서나 README가 아닌 다운로드로 바로 이어지는 경고)이 있습니다.또한 비교적 쉽게 파일을 가져올 수 있다는 것도 마찬가지입니다.fcntl그리고 당신의 것을 조작합니다.PopenPIPE 파일 설명자 직접 --- 이것이 UNIX가 아닌 플랫폼으로 이동할 수 있는지는 알 수 없습니다.

(업데이트: 2019년 8월 7일: ayncio 하위 프로세스: asyncio 하위 프로세스에 대한 Python 3 지원)

subprocess 이벤트 처리 지원이 거의 없습니다...사용할 수는 있지만,signal모듈 및 일반 구식 UNIX/Linux 신호 -- 프로세스를 부드럽게 죽입니다.

다중 처리 옵션:

multiprocessing이는 기존(Python) 코드 내에서 기능을 실행하기 위한 것으로, 프로세스 제품군 간의 보다 유연한 통신을 지원합니다.특히 고객의 비즈니스 환경을 구축하는 것이 가장 좋습니다.multiprocessing모듈변 IPC Queue가능한 경우 개체를 사용할 수도 있습니다.Event물체 및 다양한 다른 특징(일부는, 아마도, 주변에 구축됨)mmap해당 지원이 충분한 플랫폼에 대한 지원)

파이의multiprocessing모듈은 다음과 매우 유사한 인터페이스 및 기능을 제공합니다. threading또한 GIL(Global Interpreter Lock)에도 불구하고 여러 CPU/코어 간에 처리를 확장할 수 있습니다.OS 커널 개발자들이 수행한 모든 미세한 SMP 잠금 및 일관성 노력을 활용합니다.

스레드화 옵션:

threading프로세스/컨텍스트 스위칭에 비해 스레드 스위칭(공유 코어 메모리 포함)의 대기 시간과 스위칭 오버헤드가 매우 낮은 I/O 바인딩된(여러 CPU 코어에 걸쳐 확장할 필요가 없음) 매우 좁은 범위의 애플리케이션에 적합합니다.Linux에서 이것은 거의 빈 집합입니다(Linux 프로세스 스위치 시간은 스레드 스위치에 매우 가깝습니다)

threadingPython에서 두 가지 주요 단점이 있습니다.

하나는 물론 구현에 특화되어 있습니다. 주로 CPython에 영향을 미칩니다.이것이 바로 GIL입니다. 대부분의 CPython 프로그램은 두 개 이상의 CPU(코어)를 사용할 수 있는 이점이 없으며 종종 GIL 잠금 경합으로 인해 성능이 저하됩니다.

구현에 특정되지 않은 더 큰 문제는 스레드가 동일한 메모리, 신호 핸들러, 파일 설명자 및 특정 다른 OS 리소스를 공유한다는 것입니다.따라서 프로그래머는 객체 잠금, 예외 처리 및 전체 프로세스(스레드 세트)를 중지, 지연 또는 교착 상태로 만들 수 있는 코드의 다른 측면에 대해 극도로 주의해야 합니다.

에비해이해비▁bymultiprocessing모델은 각 프로세스에 자체 메모리, 파일 설명자 등을 제공합니다.충돌이나 처리되지 않은 예외는 해당 리소스를 제거할 뿐이며 자식 또는 형제 프로세스가 사라지는 것을 강력하게 처리하는 것은 스레드에서 유사한 문제를 디버깅, 격리 및 해결하거나 해결하는 것보다 훨씬 쉽습니다.

  • (으)를 합니다.threadingNumPy와 같은 주요 Python 시스템의 경우 대부분의 Python 코드보다 GIL 경합으로 인한 피해가 상당히 적을 수 있습니다.그 이유는 이를 위해 특별히 설계되었기 때문입니다. 예를 들어, NumPy의 네이티브/바이너리 부분은 안전할 때 GIL을 릴리스합니다.

트위스트 옵션:

트위스트는 우아하면서도 이해하기 매우 어려운 또 다른 대안을 제시한다는 에도 주목할 필요가 있습니다.기본적으로 트위스트 팬들이 피치포크와 횃불로 우리 집을 덮칠 정도로 지나치게 단순화될 위험을 무릅쓰고 트위스트는 어떤 (단일) 프로세스에서도 이벤트 중심의 협력적 멀티태스킹을 제공합니다.

이 기능이 어떻게 가능한지 이해하려면 의 기능에 대해 읽어야 합니다.select()select() 또는 poll() 또는 유사한 OS 시스템 호출을 중심으로 구축할 수 있습니다.기본적으로 이 모든 기능은 파일 설명자 목록에 있는 작업이나 시간 초과가 발생할 때까지 OS에 절전 요청을 할 수 있기 때문입니다.

이 각각의 전화에서 깨어나는 것은select()이벤트입니다. -- - 일부 소켓 또는 파일 설명자에서 사용 가능한 입력(가독 가능) 또는 일부 다른(쓰기 가능) 설명자 또는 소켓에서 사용 가능한 버퍼링 공간, 일부 예외 조건(예: TCP Out-of-Band PUSH'd 패킷) 또는 시간 초과 중 하나입니다.

따라서 트위스트 프로그래밍 모델은 이러한 이벤트를 처리한 다음 결과 "메인" 핸들러를 루프하여 이벤트를 핸들러로 전송할 수 있도록 합니다.

저는 개인적으로 트위스트(Twist)라는 이름이 프로그래밍 모델을 연상시킨다고 생각합니다. 왜냐하면 문제에 대한 여러분의 접근 방식은 어떤 의미에서 "뒤틀림"이 있어야 하기 때문입니다.프로그램을 입력 데이터와 출력 또는 결과에 대한 일련의 작업으로 생각하기보다는, 프로그램을 서비스 또는 데몬으로 작성하고 다양한 이벤트에 대해 프로그램이 어떻게 반응하는지 정의합니다. (사실 트위스트 프로그램의 핵심 "메인 루프"는 (일반적으로?)언제나?) areactor()).

Twisted를 사용하기 위한 주요 과제는 이벤트 중심 모델에 대한 당신의 생각을 왜곡하는 것과 Twisted 프레임워크 내에서 공동으로 작동하도록 작성되지 않은 클래스 라이브러리 또는 툴킷의 사용을 피하는 것입니다.이것이 Twist가 SSH 프로토콜 처리, 저주, 자체 하위 프로세스/Popen 함수를 위한 자체 모듈과 Python 표준 라이브러리에 있는 것을 처음에 복제하는 것처럼 보이는 많은 다른 모듈 및 프로토콜 핸들러를 제공하는 이유입니다.

Twisted는 절대 사용할 생각이 없어도 개념적인 차원에서 이해하는 것이 유용하다고 생각합니다.또한 스레딩, 멀티프로세싱 및 하위 프로세스 처리와 관련된 성능, 경합 및 이벤트 처리에 대한 통찰력과 사용자가 수행하는 모든 분산 처리에 대한 통찰력을 제공할 수 있습니다.

(참고: 최신 버전의 Python 3.x에는 asyncdef, the @async.co syslog decorator 및 wait 키워드와 같은 비동기 I/O(연속 I/O) 기능이 포함되어 있으며 향후 지원을 통해 얻을 수 있는 이점이 있습니다.이 모든 것은 프로세스(협력 멀티태스킹) 관점에서 트위스트(Twisted)와 대략 유사합니다.(Python 3에 대한 Twisted 지원의 현재 상태는 https://twistedmatrix.com/documents/current/core/howto/python3.html) 에서 확인할 수 있습니다.

분산 옵션:

아직 질문하지 않았지만 고려할 가치가 있는 또 다른 처리 영역은 분산 처리입니다.분산 처리 및 병렬 계산을 위한 많은 Python 도구와 프레임워크가 있습니다.개인적으로 저는 가장 사용하기 쉬운 것은 그 공간에 있는 것으로 가장 적게 간주되는 것이라고 생각합니다.

Redis를 중심으로 분산 프로세싱을 구축하는 것은 거의 사소한 일입니다.전체 키 저장소는 작업 단위와 결과를 저장하는 데 사용할 수 있으며, Redis LIST는 다음과 같이 사용할 수 있습니다.Queue()object, PUB/은 유사객체, 그리고 PUB/SUB 될수있다에 될 수 .Event- 핸들링과 유사합니다.Redis 인스턴스의 느슨한 클러스터에서 복제된 키를 해시하고 값을 사용하여 토폴로지 및 해시 토큰 매핑을 저장함으로써 단일 인스턴스의 용량을 초과하는 확장을 위한 일관된 해시 및 페일오버를 제공하여 작업자와 데이터(피클, JSON, BSON 또는 YAML)를 조정할 수 있습니다.

물론 Redis를 중심으로 보다 규모가 크고 정교한 솔루션을 구축하기 시작하면 Celery, Apache Spark and Hadoop, Zookeper 을 사용하여 이미 해결된 많은 기능을 다시 구현하게 됩니다.이들은 모두 서비스에 대한 Python 액세스를 위한 모듈을 가지고 있습니다.

[업데이트:분산 시스템 전반에서 계산 집약적인 Python을 고려할 때 고려해야 할 몇 가지 리소스:아이피톤 병렬 및 파이스파크.이러한 시스템은 범용 분산 컴퓨팅 시스템이지만 특히 액세스가 용이하고 인기 있는 하위 시스템 데이터 과학 및 분석]입니다.

결론

단일 스레드, 단순한 동기 호출, 하위 프로세스, 폴링된 하위 프로세스 풀, 스레드 및 멀티프로세싱, 이벤트 기반 협업 멀티태스킹, 분산 처리에 이르기까지 Python을 위한 대체 프로세스의 대부분을 사용할 수 있습니다.

multiprocessing훌륭한 스위스-군용 나이프 유형의 모듈입니다.원격 계산도 수행할 수 있기 때문에 스레드보다 일반적입니다.따라서 이것이 제가 사용하기를 제안하는 모듈입니다.

subprocess모듈은 또한 당신이 여러 프로세스를 시작할 수 있게 해주지만, 저는 그것이 새로운 멀티프로세싱 모듈보다 사용하기에 덜 편리하다는 것을 알았습니다.

스레드는 매우 미묘하기로 악명 높고, CPython을 사용하면 종종 하나의 코어로 제한됩니다(댓글 중 하나에서 언급한 것처럼 글로벌 인터프리터 잠금(GIL)이 Python 코드에서 호출된 C 코드로 릴리스될 수 있음).

저는 당신이 언급한 세 가지 모듈의 대부분의 기능이 플랫폼 독립적인 방식으로 사용될 수 있다고 생각합니다.휴성측서보면에면대,보면▁that▁on서,,multiprocessingPython 2.6 이후에만 표준으로 제공됩니다(그러나 일부 이전 버전의 Python용 버전은 존재함).하지만 그것은 훌륭한 모듈입니다!

CPyth에서 여러 프로세서를 사용하는 유일한 선택은 모듈입니다.Cython은 다른 CPU의 스레드가 병렬로 작동하지 않도록 내부(GIL)를 잠급니다.multiprocessing프로세스를 예:subprocess 및합니다.을 수행하고 이들 간의 통신을 관리합니다.

비슷한 경우에 저는 별도의 프로세스와 약간의 필요한 통신을 네트워크 소켓을 통해 선택했습니다.python을 사용하여 수행하는 것은 매우 휴대성이 높고 매우 간단하지만, 아마도 더 간단하지 않을 것입니다(나의 경우에는 다른 제약 조건도 있었습니다: C++로 작성된 다른 프로세스와의 통신).

당신의 경우, 적어도 CPython을 사용할 때 파이썬 스레드는 실제 스레드가 아니기 때문에 아마도 멀티프로세스를 위해 갈 것입니다.기본 시스템 스레드이지만 Python에서 호출된 C 모듈은 GIL을 해제하거나 해제하지 않을 수 있으며 차단 코드를 호출할 때 다른 스레드가 실행되도록 허용할 수도 있습니다.

작업을 수행하기 위해 unix를 실행합니다.

인터파이프를 사용하여 하위 프로세스를 래핑한 다음:

테드 주바의 사이트에서.

INPUTES_FROM_YOU | xargs -n1 -0 -P NUM ./process #Num 병렬 프로세스

OR

Gnu Parallel은 또한 서비스를 제공할 입니다.

당신은 GIL과 어울리고 당신의 멀티코어 일을 위해 뒷방 소년들을 밖으로 내보냅니다.

프로그램이 무엇을 할 것인지 확신할 수 없습니다. 요청을 사용하는 API 로드 테스트를 실행하는 동안 이 스레드를 발견했습니다.위의 모든 제안은 매우 상세했습니다.

결국 가장 좋은 결과는 grequests 또는 a를 사용하는 것이었고, 이는 곧 aiohttp로 발전했습니다.

Grequests:Python 요청을 포함한 비동기 요청

aiohttp 스타터: https://pythonalgos.com/send-api-requests-asynchronously-in-python/

언급URL : https://stackoverflow.com/questions/2629680/deciding-among-subprocess-multiprocessing-and-thread-in-python