asyncio를 사용하다가 혼동되는 부분이 많다. 대표적으로는 Task
와 Future
의 차이가 있을 것이다. asyncio.create_task()와 asyncio.ensure_future() 또한 혼동되는 부분이다. 예제 코드를 찾아보면 ensure_future를 사용하는 코드도 간간히 볼 수 있었다. 두 함수 모두 코루틴을 실행하기 위해 사용될 수 있기 때문에 혼용해서 쓰는 경우가 많은 것 같다. 각 함수의 역할을 더 정확히 알아보고 이에 대해 정리했다.
ximport asyncio
async def f():
pass
coro = f()
loop = asyncio.get_event_loop()
task1 = loop.create_task(coro)
assert isinstance(task1, asyncio.Task)
task2 = asyncio.ensure_future(coro)
assert isinstance(task2, asyncio.Task)
task3 = asyncio.ensure_future(task1)
assert task3 is task1
두 함수의 차이점을 알아보기 위해 위 코드를 작성했다. 코드를 살펴보면 loop.create_task()와 asyncio.ensure_future() 함수를 사용해 코루틴 f()
를 각각 task1
, task2
로 만들었다. 마지막 코드를 보면 create_task()로 만들어진 task1
을 ensure_future()의 인자로 전달해 만든 task3
이 task1
과 동일한 것을 알 수 있다. 즉 인자로 들어온 task1을 그대로 반환한 것이다.
ensure_future() 함수는 인자가 코루틴일 경우 Task를 반환하고, 인자가 Task나 Future의 경우 인자 그대로 반환한다. 이것이 어떤 의미가 있을까? 해당 함수의 동작을 보면 ensure_future()가 반환하는 값은 항상 Future가 되는 것을 알 수 있다. Future에만 정의된 메서드를 호출해야할 경우 ensure_future함수를 사용해 Future일 수 있는 인스턴스가 Future형이라는 것을 확실히 알 수 있다.
따라서 일반적으로 태스크를 생성해야하는 상황에서는 create_task()를 사용하는 것이 적합하다.
칼렙 하팅, Using Asyncio in Python. Understanding Python's Asynchronous Programming Features, 한빛 미디어