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 이후.
  • Tornado 와 Twisted 는 Python2.7 부터 준비되었습니다.
  • uvloop 는 매우 빠른 asyncio이벤트 루프입니다 ( uvloop 는 asyncio2-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.