[Python] Asyncio
asyncio
asyncio는 asycn/await 구문을 사용하여 동시성 코드를 작성하는 라이브러리다.
asyncio는 고성능 네트워크 및 웹서버, 데이터베이스 연결 라이브러리, 분산 작업 큐 등을 제공하는 여러 파이썬
비동기 프레임워크의 기반으로 사용된다.
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())
asyncio는 다음과 같은 API를 제공한다.
고수준 API | 코루틴, 네트워크 IO/IPC, Queue, 동기화 |
저수준 API | 이벤트 루프, Transport, Future |
Runner
asyncio.run(coro, *, debug=None, loop_factory=None)
# example
async def main():
await asyncio.sleep(1)
print('hello')
asyncio.run(main())
전달된 코루틴을 실행하여 asyncio 이벤트 루프를 관리하고, 비동기 생성기를 완료하고, 실행자를 닫는다.
동일한 스레드에서 다른 asyncio 이벤트 루프가 실행 중일 때는 이 함수를 호출 할 수 없다.
# class
asyncio.Runner(*, debug=None, loop_factory=None)
# example
async def main():
await asyncio.sleep(1)
print('hello')
with asyncio.Runner() as runner:
# 내장된 루프에서 코루틴을 실행
runner.run(main())
# 러너를 닫음
runner.close()
동일한 컨텍스트에서 여러 비동기 함수 호출을 단순화하는 컨텍스트 관리자다.
이벤트 루프
이벤트 루프는 모든 asyncio 응용 프로그램의 핵심이다. 이벤트 루프는 비동기 Task 및 Callback을 실행하고, 네트워크 IO 연산을 수행하며 자식 프로세스를 실행한다.
💡 이벤트 루프
하나의 스레드에서 여러 비동기 작업을 관리하는 장치다.
주어진 작업이 완료될 때까지 대기하지 않고, 다른 작업을 동시에 진행할 수 있도록 함으로써 비동기 I/O를 효율적으로 처리한다.
asyncio 모듈은 이벤트 루프와 비동기 프로그래밍을 위한 도구를 제공한다.
asyncio.get_event_loop()를 통해 이벤트 루프에 접근할 수 있으며, 함수로 정의된 비동기 함수를 await를 통해 실행할 수 있다.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1) # 1초 대기
print("World!")
async def main():
# say_hello 함수를 동시에 실행
await asyncio.gather(say_hello(), say_hello())
asyncio.run(main())
위 예제에서 say_hello 함수는 sleep(1) 동안 다른 작업을 수행할 수 있도록 await을 사용해 이벤트 루프에 제어권을 반환한다.
코루틴(Coroutine)과 테스크(Tasks)
코루틴은 비동기 함수를 의미하며, async def로 정의한다.
코루틴 함수는 실행되기 전에는 아무런 동작도 하지 않고, 단지 실행 할 준비가 된 상태로 존재한다. 코루틴을 실행하려면 await 키워드들 사용하거나 task로 스케줄링을 해야한다.
Task는 코루틴을 이벤트 루프에 등록하고 실행하는 객체다.
코루틴을 단독으로 실행하면 순차적으로 실행되지만, 테스크로 스케줄링하면 여러 코루틴을 동시에 실행할 수 있다.
async def my_coroutine():
print("Coroutine started")
await asyncio.sleep(1)
print("Coroutine ended")
# 코루틴을 task로 만들어 스케줄링
async def main():
task = asyncio.create_task(my_coroutine())
await task
asyncio.run(main())
위 코드에서 my_coroutine()은 create_task()로 task가 되어 이벤트루프에 스케줄링된다.
이벤트루프는 다른 작업을 병렬적으로 처리하면서 await, task 구문에서 테스크가 끝나기를 기다린다.
asyncio에서는 퓨처와 테스크가 밀접한 관계에 있다.
💡 퓨처 (Future)
퓨처는 asyncio의 중요한 개념 중 하나로, 아직 완료되지 않은 작업의 결과를 나타내는 객체다.
Future 객체는 비동기 작업이 끝난 이후에 그 결과를 담거나 예외 정보를 담아 전달하는 용도로 사용된다.
쉽게 말해, "나중에 결과가 채워질 빈 약속" 이라고 할 수 있다.
퓨처는 곧 채워질 작업을 의미하지만, 실제로 실행하는 코드나 작업을 담고 있지는 않다.
테스크는 퓨처의 하위 개념으로, 코루틴 실행과 동시에 퓨처의 역할을 하여 비동기 작업의 결과를 제공한다.
참고
https://docs.python.org/ko/3/library/asyncio.html
'👩💻 Develope > Python' 카테고리의 다른 글
[Python] 동시성 프로그래밍 (2) 코루틴(Coroutine) (0) | 2024.11.12 |
---|---|
[Python] 동시성 프로그래밍 (1) 프로세스, 스레드 (0) | 2024.11.05 |
[Python] pip freeze 명령어 사용 시 패키지 버전이 제대로 나오지 않을 때 (0) | 2024.10.14 |
[Python][bs4] BeautifulSoup4에서 텍스트로 파싱하기 (0) | 2024.10.08 |
[Python] glob (1) | 2024.09.26 |