- 코루틴 기본 개념
Future 객체
Future는 아직 완료되지 않은 작업의 결과를 나타내는 데이터 구조입니다. 이벤트 루프는 Future 객체의 완료 여부를 모니터링할 수 있으며, 이를 통해 애플리케이션의 일부분이 다른 부분의 작업 완료를 기다릴 수 있습니다.
Future 객체는 다음과 같은 상태를 가집니다:
- Pending (대기 중)
- Running (실행 중)
- Done (완료됨)
- Cancelled (취소됨)
Future 객체가 생성될 때 상태는 Pending이며, 이벤트 루프가 실행을 호출하면 Running 상태가 됩니다. 실행이 완료되면 Done 상태가 되며, 이벤트 루프를 중지해야 할 경우 먼저 Task를 취소하여 Cancelled 상태로 만들어야 합니다.
Task 객체
Task는 Future의 하위 클래스로, 코루틴 실행을 래핑하고 관리하는 방법을 알고 있습니다. Task에 필요한 리소스가 사용 가능해지면, 이벤트 루프는 Task를 실행하도록 예약하고 결과를 생성하여 다른 코루틴이 이를 소비할 수 있도록 합니다.
event_loop 이벤트 루프: 프로그램이 무한 루프를 시작하고, 개발자는 특정 함수들을 이벤트 루프에 등록합니다. 이벤트가 발생했을 때 해당 코루틴 함수가 호출됩니다.
coroutine 코루틴: async 키워드로 정의된 함수를 의미하며, 함수를 즉시 실행하는 대신 코루틴 객체를 반환합니다. 코루틴 객체는 이벤트 루프에 등록되어 이벤트 루프에 의해 호출됩니다.
task 작업: 코루틴 객체는 원래부터 일시 중단 가능한 함수이며, 작업은 코루틴을 추가로 래핑한 것으로 작업의 다양한 상태를 포함합니다.
async/await 키워드: Python 3.5에서 코루틴을 정의하기 위한 키워드로, async는 코루틴을 정의하고 await은 차단되는 비동기 호출 인터페이스를 일시 중단하는 데 사용됩니다.
Python 코루틴 및 asyncio 기초
코루틴(coroutine)은 또 다른 형태의 다중 작업 구현 방식으로, 스레드보다 더 작은 실행 단위이며 일반적으로 단일 프로세스와 단일 스레드에서 실행됩니다. CPU 컨텍스트를 자체적으로 가지고 있으므로 간단한 이벤트 루프를 통해 작업 전환이 가능하며, 프로세스와 스레드의 전환 효율보다 높습니다. 이는 프로세스와 스레드 전환이 운영체제에 의해 이루어지기 때문입니다.
Python에서 코루틴을 구현하는 주요 방법은 asyncio와 gevent 두 가지 라이브러리를 사용하는 것입니다. asyncio가 Python 표준 라이브러리이므로 pip 설치 없이 사용할 수 있어, Python의 네이티브 코루틴 구현 방식으로 더 널리 사용될 것입니다.
asyncio는 Python 3.4에서 도입된 표준 라이브러리로, 코루틴 비동기 IO에 대한 직접적인 지원을 내장하고 있습니다. asyncio의 프로그래밍 모델의 본질은 메시지 루프이며, 일반적으로 먼저 코루틴 함수(또는 작업)를 정의하고 asyncio 모듈에서 이벤트 루프 loop를 가져와 실행할 코루틴 작업(또는 작업 목록)을 loop에 전달하여 비동기 IO를 구현합니다.
코루틴 함수 정의 및 실행 방식의 변화
최초의 Python 3.4에서는 @asyncio.coroutine과 yield from을 사용하여 코루틴 함수를 구현했습니다. 다음과 같습니다.
import asyncio
@asyncio.coroutine
def sample_coroutine(task_id):
print("코루틴 함수 {}가 곧 실행됩니다.".format(task_id))
yield from asyncio.sleep(2)
print("코루틴 함수 {}가 실행 완료되었습니다!".format(task_id))
if __name__ == '__main__':
# 이벤트 루프 가져오기
loop = asyncio.get_event_loop()
# 코루틴 작업 실행
loop.run_until_complete(sample_coroutine(1))
# 이벤트 루프 닫기
loop.close()
여기서 sample_coroutine이라는 코루틴 함수를 정의했습니다. asyncio.iscoroutinefunction을 사용하여 검증할 수 있습니다. 코루틴 함수를 정의한 후, 먼저 이벤트 루프 loop를 가져와서 run_until_complete 메서드로 코루틴 작업을 실행한 다음 loop를 닫습니다.
print(asyncio.iscoroutinefunction(sample_coroutine(1))) # True