Python을 사용한 비동기 실행(Pt. 1)
Python
asyncio
라이브러리를 사용하면 I/O 바인딩 전략을 위한 동시 코드를 작성할 수 있습니다. 이는 CPU 바운드 전략을 위한 스레드 사용에 중점을 둔 라이브러리multiprocessing
와 다릅니다.asyncio
/async
키워드와 함께 await
라이브러리는 "이벤트 루프"라는 개념을 사용하여 이를 가능하게 합니다. 이는 비동기 루프 및 기능을 생성하고 예약하는 추상적인 방법을 제공합니다. 브라우저의 프런트 엔드 상호 작용에 사용되는 JavaScript도 이벤트 루프 개념을 기반으로 하므로 이 개념을 비교/검토하기에 완벽한 언어입니다.Note: Some of the
asyncio
functions implemented in Python 3.7+ may beDeprecated
in Python 3.10+
동기식 실행
일반적으로 Python 및 대부분의 다른 절차적 언어로 프로그래밍할 때 프로그램은 위에서 아래로 실행됩니다(코드가 구조화되지 않은 경우에도 언어 해석/컴파일러 참조). 즉, 각 문은 이전 문(들)이 완료된 후에 실행됩니다.
예를 들어, 지정된
random_add
(초 단위) 다음에 임의의 정수 목록을 합산하는 delay
함수가 있다고 가정합니다.def random_add(delay: int) -> None:
import time
time.sleep(delay)
# This retrieves a list of random ints
n = random_number_list()
print(f'Sum({n}) = {sum(n)}')
이 함수를 연속해서 3번 실행합니다.
if __name__ == "__main__":
random_add(5) # call1: Delayed 5s
random_add(8) # call2: Delayed 8s
random_add(2) # call3: Delayed 2s
총 타이밍은 15초에 가깝습니다. 다음과 같이 각 호출이 하나씩 완료됩니다below.
random_add
함수가 지연된 기간 동안 계산을 수행하지 않더라도 해당 기간 동안 할당된 리소스가 여전히 있습니다. 이것이 일반적인 동기식 프로그램의 시간 소비가 일반적으로 모든 프로시저의 합계로 설명될 수 있는 이유입니다.동기 타이밍
전화
시작
마치다
주문 완료
1
0초
5초
1
2
5초
13초
2
삼
13초
15초
삼
비동기 실행
이전
random_add
함수를 재사용하고 비동기적으로 실행하도록 조정할 수 있습니다.import asyncio
async def random_add(delay: int) -> None:
asyncio.sleep(delay)
# This retrieves a list of random ints
n = random_number_list()
print(f'Sum({n}) = {sum(n)}')
이제 이전과 마찬가지로 이 함수를 3번 실행합니다.
if __name__ == "__main__":
await random_add(5)
await random_add(8)
await random_add(2)
어 오! 다음과 유사한
SyntaxError
를 수신해야 합니다. await random_add(5)
^^^^^^^^^^^^^^^^^^^
SyntaxError: 'await' outside function
이 문제는 Python 스크립트를 실행하기 전에 사용 중인 IDE에서 감지되었을 수도 있습니다.
await
는 async
범위에서만 사용할 수 있고 main
스레드는 이벤트 루프 없이 동기식이기 때문입니다! 이 코드를 실행하려면 다음을 수행해야 합니다.이 코드를
async
함수로 래핑합니다.async def async_test():
await random_add(5)
await random_add(8)
await random_add(2)
그런 다음
asyncio.run
기능을 활용하십시오.if __name__ == "__main__":
asyncio.run(async_test())
이제 코드가 행복하게 실행되어야 합니다. 그러나 코드를 실행하는 데 여전히 동일한 시간이 걸립니다. 왜 그런 겁니까?
async
병렬로 작동하지 않습니까?그 이유는
await
키워드가 상위 함수가 다음 명령문으로 계속 진행하기 전에 결과를 대기함을 의미하기 때문입니다. 응답이 지연되므로 해당 기간 동안 대기합니다.random_add
함수 호출을 동시에 실행하려면 실행할 Task
를 만들어야 합니다. 이는 asyncio.create_task
를 통해 개별적으로 수행할 수 있습니다.async def async_test_task():
task1 = asyncio.create_task(random_add(5))
task2 = asyncio.create_task(random_add(8))
task3 = asyncio.create_task(random_add(2))
await task1, await task2, await task3
또는 작업 목록을 보려면
asyncio.gather
를 통해:async def async_test_gather():
await asyncio.gather(
random_add(5),
random_add(8),
random_add(2)
)
이 게시물의 나머지 부분에서는 단순화를 위해
asyncio.gather
를 활용합니다. asyncio.create_task
를 적용할 수 있는 특정 시나리오(예: 가변 작업 생성)가 있습니다.이제 코드가 조정되었으므로 총 실행 시간이 가장 느린 작업에 의해서만 제한된다는 것을 알 수 있습니다! 또한 각 작업이 완료되는 순서도 다릅니다(표시됨below ).
비동기 타이밍
전화
시작
마치다
주문 완료
1
0초
5초
2
2
~0초
8초
삼
삼
~0초
2초
1
이것은 Python의
async
/await
및 asyncio
라이브러리에서 제공하는 기능의 시작일 뿐입니다. 이 개요가 릴리스되면 이 개요의 파트 2를 반드시 읽으십시오.
Reference
이 문제에 관하여(Python을 사용한 비동기 실행(Pt. 1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/avonbied/asynchronous-execution-with-python-pt-1-3lfj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)