Python 3의 다중 처리 대 다중 스레딩 대 asyncio


107

Python 3.4에는 다중 처리 / 스레딩을위한 몇 가지 다른 라이브러리가 있음을 발견했습니다. 다중 처리스레드asyncio .

하지만 어떤 것을 사용해야하는지 또는 "권장"인지 모르겠습니다. 같은 일을합니까, 아니면 다른가요? 그렇다면 어떤 용도로 사용됩니까? 내 컴퓨터에서 멀티 코어를 사용하는 프로그램을 작성하고 싶습니다. 하지만 어떤 라이브러리를 배워야할지 모르겠습니다.


1
어쩌면 나는 AsyncIO가 너무 멍청 하는 데 도움이
마틴 토마스

답변:


81

(약간) 다른 목적 및 / 또는 요구 사항을위한 것입니다. CPython (일반적인 주요 Python 구현)에는 여전히 전역 인터프리터 잠금이 있으므로 다중 스레드 응용 프로그램 (요즘 병렬 처리를 구현하는 표준 방법)은 차선책입니다. 이유 multiprocessing 보다 선호한다 threading. 그러나 모든 문제가 [거의 독립적 인] 조각으로 효과적으로 분할되는 것은 아니므로 과도한 프로세스 간 통신이 필요할 수 있습니다. 그렇기 때문에 일반적 multiprocessing으로 선호되지 않을 수 있습니다 threading.

asyncio(이 기술은 Python뿐만 아니라 다른 언어 및 / 또는 프레임 워크에서도 사용할 수 있습니다 (예 : Boost.ASIO ))은 병렬 코드 실행 없이도 여러 소스의 많은 I / O 작업을 효과적으로 처리하는 방법입니다. . 따라서 일반적인 병렬 처리가 아닌 특정 작업에 대한 솔루션 (실제로 좋은 것입니다!)입니다.


7
세 가지 모두 병렬 처리를 달성하지 못할 수 있지만 모두 동시 (비 차단) 작업을 수행 할 수 있습니다.
sargas

68

[빠른 답변]

TL; DR

올바른 선택 :

가장 많이 사용되는 동시성 형식을 살펴 보았습니다. 그러나 질문은 남아 있습니다-언제 어느 것을 선택해야합니까? 실제로 사용 사례에 따라 다릅니다. 내 경험과 독서에서 나는 다음과 같은 의사 코드를 따르는 경향이 있습니다.

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • CPU 바운드 => 다중 처리
  • I / O 바운드, 빠른 I / O, 제한된 연결 수 => 다중 스레딩
  • I / O 바운드, 느린 I / O, 많은 연결 => Asyncio

참고


[ 참고 ] :

  • 긴 호출 메서드 (예 : 휴면 시간 또는 지연 I / O가 포함 된 메서드)가있는 경우 최상의 선택은 동시성으로 단일 스레드와 함께 작동하는 asyncio , Twisted 또는 Tornado 접근 방식 (코 루틴 메서드)입니다.
  • asyncio는 작동 Python3.4 이후.
  • TornadoTwistedPython2.7 부터 준비되었습니다.
  • uvloop 는 매우 빠른 asyncio이벤트 루프입니다 ( uvloopasyncio2-4 배 더 빠름).

[업데이트 (2019)] :

  • Japranto ( GitHub )uvloop 기반의 매우 빠른 파이프 라이닝 HTTP 서버입니다 .

따라서 요청할 URL 목록이 있으면 Asyncio 를 사용하는 것이 좋습니다 .
mingchau

1
@mingchau, 예,하지만 asyncio대기 가능한 함수에서 사용할 때 사용할 수 있다는 점을 명심하십시오. request라이브러리는 대기 가능한 방법이 아니라 aiohttp라이브러리 또는 비동기 요청 등과 같이 사용할 수 있습니다 .
Benyamin Jafari

slowIO 및 fastIO를 확장하여 다중 스레드 또는 asyncio>로 이동하십시오.
qrtLs

@qrtLs SlowIO가있을 때 AsyncIO는 매우 유용하고 효율적입니다.
Benyamin Jafari 19 년

1
@variable I / O 바운드는 프로그램이 네트워크 연결, 하드 드라이브, 프린터 또는 절전 시간이있는 이벤트 루프와 같은 느린 장치와 통신하는 데 대부분의 시간을 소비 함을 의미합니다. 따라서 차단 모드에서는 스레딩 또는 asyncio 중에서 선택할 수 있으며 경계 섹션이 매우 느린 경우 협력 적 멀티 태스킹 (asyncio)이 더 나은 선택입니다 (예 : 리소스 부족, 교착 상태 및 경쟁 조건 방지)
Benyamin Jafari

8

이것이 기본 아이디어입니다.

그것은인가 IO -bound? ---------> 사용asyncio

IT IS CPU - 무거운는? -----> 사용multiprocessing

그렇지 않으면? ----------------------> 사용threading

따라서 기본적으로 IO / CPU 문제가없는 한 스레딩을 고수하십시오.


0

다중 처리 에서는 여러 CPU를 활용하여 계산을 분산합니다. 각 CPU가 병렬로 실행되기 때문에 여러 작업을 동시에 효과적으로 실행할 수 있습니다. CPU 바운드 작업에 다중 처리를 사용하려고 합니다. 예를 들어 거대한 목록의 모든 요소의 합계를 계산하려고합니다. 시스템에 8 개의 코어가있는 경우 목록을 8 개의 작은 목록으로 "자르고"개별 코어에서 각 목록의 합계를 개별적으로 계산 한 다음 해당 숫자를 더할 수 있습니다. 그렇게함으로써 ~ 8 배의 속도 향상을 얻을 수 있습니다.

에서 스레딩여러 CPU가 필요하지 않습니다. 웹에 많은 HTTP 요청을 보내는 프로그램을 상상해보십시오. 단일 스레드 프로그램을 사용하는 경우 각 요청에서 실행 (블록)을 중지하고 응답을 기다린 다음 응답을 받으면 계속합니다. 여기서 문제는 외부 서버가 작업을 수행하기를 기다리는 동안 CPU가 실제로 작업을 수행하지 않는다는 것입니다. 그 동안 실제로 유용한 작업을 수행 할 수있었습니다! 해결 방법은 스레드를 사용하는 것입니다. 스레드를 많이 만들 수 있으며 각 스레드는 웹에서 일부 콘텐츠를 요청합니다. 스레드의 좋은 점은 CPU가 하나의 CPU에서 실행 되더라도 CPU가 때때로 한 스레드의 실행을 "고정"하고 다른 스레드를 실행하도록 점프한다는 것입니다 (컨텍스트 전환이라고하며 이는 비 결정적 간격). -스레딩을 사용하십시오.

asyncio 는 기본적으로 CPU아닌 곳에서 스레딩을 수행 하지만 프로그래머 (또는 실제로 응용 프로그램)로서 컨텍스트 전환이 발생하는 위치와시기를 결정 합니다. Python에서는 await키워드를 사용 하여 코 루틴의 실행을 중지합니다 (키워드를 사용하여 정의 됨 async).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.