[Python] 비동기 프로그래밍 정리 2 (Future, Task)

hodu·2022년 10월 31일
1

asyncio

목록 보기
2/7
post-thumbnail

아래 링크를 읽고 정리한 내용입니다.

🚨 더 구체적인 내용은 아래 링크에 아주 친절하게 잘 정리되어 있으니 꼭 링크가서 읽어주세요!!
https://it-eldorado.tistory.com/159?category=749661


이번에는 코루틴 객체와 비슷하면서 다른 Future, Task 객체에 대해 정리해보도록 하자.
Future, Task 모두 await 뒤에 올 수 있는 Awaitable 한 객체에 해당하며 비동기 프로그래밍에서 아주 핵심적인 역할을 한다.

1. Future

Future 객체는 어떠한 작업의 실행 상태 및 결과를 저장하는 객체이다.

여기서 말하는 "실행 상태"란 해당 작업이 진행 중인지, 취소되었는지, 종료되었는지를 말한다.
그래서 퓨쳐 객체는 PENDING, CANCELLED, FINISHED의 상태 중 하나를 가지게 된다.

  • 작업 완료(Done) : CALCELLED, FINISHED
  • 작업 진행 : PENDING

🚨 주의)
취소되어도 완료 상태
예외가 발생한 경우에도 FINISHED가 된다.

퓨쳐 객체의 중요한 메서드 중 하나는 add_done_callback()이다. 이 메서드를 호출하였을 경우 해당 퓨쳐 객체가 완료될 때 호출 될 함수를 등록할 수 있다.
(이 메서드를 통해 이벤트 루프 동작원리를 설명할 수 있으므로 기억해두자.)

🚨 주의)
Future객체는 어떠한 작업의 실행 상태, 결과를 저장할 뿐 그 작업의 실행을 개시하는 역할을 수행하지는 않는다.

2. Task

Future를 상속하는 클래스이며 Future객체와 마찬가지로 어떠한 작업의 실행 상태 및 결과를 저장한다.
Future 객체와 다른 점은 어떠한 작업의 "실행"까지 개시한다는 점이며 이를 위해 필요한 것이 코루틴 객체이다. 실제로 태스크 객체는 코루틴 객체를 가지고 있는 특별한 종류의 퓨쳐 객체이며 실제로 태스크 객체는 생성될 때 코루틴 객체를 넘겨받아 __coro필드에 저장한다.

즉, 태스크 객체는 코루틴 객체를 가지고 있는 특별한 종류의 퓨쳐 객체라고 볼 수 있다.

다만, 코루틴 객체와 달리 코루틴을 호출한다고 해서 생성, 반환되는 것은 아니며 태스크 객체를 생성하기 위해서는 asyncio.run()이나 asyncio.create_task()함수를 호출할 때 인자로 코루틴 객체를 넘겨줘야 한다.

Task 객체 실행 순서

  1. asyncio.run()이나 asyncio.create_task()를 호출하게 되면 태스크 객체가 생성된다.

  2. 생성됨과 동시에 __step() 메서드를 호출할 것을 요청한다.
    __step()은 자신의 코루틴 객체를 이용하여 해당 코루틴을 실행하는 메서드이다. 👉 코루틴이 태스크로써 실행되도록 이벤트 루프에 예약을 건다고 함

  3. __step() 메서드를 통해 코루틴 실행이 개시되며, 처음 실행된 코루틴은 await 키워드를 이용하여 또 다른 코루틴을 부르거나 그 코루틴이 또다시 다른 코루틴을 부를 수도 있다. 👉 코루틴 체인

  4. 코루틴을 연속적으로 호출하다보면 sleep이나 I/O 관련하여 await하는 코루틴을 마주칠 수 있다. 이 떄 태스크 객체는 자신의 실행을 중단하고 이벤트 루프에게 제어권을 넘긴다.
    이벤트 루프는 자신에게 실행을 예약해둔 태스크들 중 우선순위가 높은 것을 적절히 선택하여 이를 실행하게 되고 아까 실행 중이던 태스크가 다시 실행할 수 있는 상태가 되면 이 태스크는 다시 이벤트 루프에게 실행을 예약해둔다.

  5. 모든 yield 키워드를 소진한 상태에서 returnStopIteration 예외가 발생하게되면 코루틴 실행이 완료된 것이다. 그러면 그 객체로부터 반환 값을 얻고 자기 자신(태스크 객체)의 결과 값을 업데이트 한다.

자기 자신의 결과값을 업데이트 한다는 것은 태스크의 실행이 완료되었다는 뜻이며 이제 더이상 이벤트 루프에 의해 실행이 예약될 수 없는 상태를 의미한다.
참고로 asyncio.run() 함수가 실행되는 것은 이로 인해 실행된 태스크의 실행이 완료될 때까지를 의미하는 것이다.


다음 게시글에서는 이벤트 루프의 실행 흐름(동작 원리)에 대해 정리해보도록 하겠다.

profile
안녕 세계!

0개의 댓글