궁금한게 많은 개발자 노트

[ python ] future / task object 본문

Language

[ python ] future / task object

궁금한게 많은 개발자 2023. 4. 16. 16:49

Future Object

퓨처 객체는 어떠한 작업의 실행 상태 및 결과를 저장하는 객체입니다. 실행 상태란 해당 작업이 진행 중인지(PENDING), 취소되었는지(CANCELLED), 종료되었는지(FINISHED)를 나타냅니다. 작업의 완료라 함은 CANCELLED 또는 FINISHED 상태를 가리킵니다. 

그리고 실행 결과라 함은 해당 작업의 결과 값 혹은 그 작업을 진행하면서 발생한 예외 객체를 말합니다. 예외가 발생한 경우에도 상태는 FINISHED가 됨을 주의해야 합니다.

중요한 점으로는 작업의 실행 상태 및 결과를 나타낼 뿐, 작업의 실행을 개시하지 않는다는 점입니다.

 

퓨처 객체의 중요한 메소드 중하나는 add_done_callback()입니다. 이 메소드를 호출하면 해당 퓨처 객체가 완료될 떄 호출할 함수를 등록할 수 있습니다. event loop의 동작 원리를 설명할 때 중요한 내용입니다.  

 

 

 

Task Object

테스크는 퓨처를 상속하는 클래스입니다. 즉, 테스크는 기본적으로 퓨처 객체의 기능을 전부 가지고 있으므로 작업의 실행 상태나 결과를 저장합니다. 그러나 중요한 차이점으로 테스크 객체는 어떠한 작업의 실행을 개시하는 역할도 수행합니다.

이를 위해 필요한 것이 바로 coroutine 객체입니다. 실제로 task 객체는 생성될 때 coroutine객체를 넘겨받아 _coro 필드에 저장합니다. 결국 테스크 객체는 코루틴 객체를 갖고 있는 특별한 종류의 퓨처 객체입니다.

 

task를 생성하려면 asyncio.run(), asyncio.create_task()함수를 호출할 때 coroutine객체를 넘겨주면서 해당 coroutine을 가지는 task를 생성합니다. task객체는 생성되는 즉시 현재 thread에 설정되어 있는 event loop에 자신의 __step() method를 호출해줄 것을 요청합니다. __step()은 자신의 _coro변수(coroutine객체)를 이용하여 해당 coroutine을 실행하는 메소드입니다. 이러한 과정을 coroutine이 task로서 실행되도록 event loop에 예약한다라고 표현할 수 있습니다.

task객체를 생성하는 asyncio.run(), asyncio.create_task()함수를 호출할 때 coroutine객체를 인자로 넘겨주고, 넘겨준 coroutine으로 task객체가 생성되면서 event loop에 해당 coroutine이 task로 실행되도록 예약됩니다.

 

task객체의 __step()메소드가 호출되면 coroutine이 실행되고, 해당 coroutine은 await키워드로 다른 coroutine을 호출할 수있고, 이러한 방식으로 여러 coroutine의 chain이 형성됩니다.

이러한 연쇄 과정으로 coroutine을 호출하다보면 sleep혹은 I/O관련 coroutine을 await하는 코드를 마주칠 수 있습니다. task는 이러한 상황을 감지하면 자신의 실행을 중단하고, event loop에게 제어권을 넘깁니다. event loop는 제어권을 얻으면 task(coroutine) queue에서 우선순위가 높은 것을 선택하여 실행하고, I/O바운드 작업이 완료된 task가 다시 실행 가능한 상태가 되면 이 task는 다시 event loop에 실행을 예약하여 task queue에 들어갑니다.

 

task객체가 처음 실행한 coroutine의 실행이 완료되면, 즉 해당 coroutine이 모든 yield 키워드를 소진한 상태에서 return 함으로써 StopIteration 예외가 발생하고, 그 coroutine객체로부터 반환 값을 얻어 자신(task)의 결과 값을 업데이트합니다.

이는 task의 실행이 완료 됨을 의미하며, 해당 task는 더 이상 event loop에 예약할 필요가 없습니다.

(asyncio.run()함수의 실행은 coroutine에 의해 실행되는 task의 실행이 완료될 때 까지 대기를 의미합니다)

 

 

 

참고한 링크: https://it-eldorado.tistory.com/159?category=749661 

 

[Python] 비동기 프로그래밍 동작 원리 (asyncio)

JavaScript와 달리 Python은 비동기 프로그래밍에 어색하다. 애초에 JavaScript는 비동기 방식으로 동작하도록 설계된 언어인 반면, Python은 동기 방식으로 동작하도록 설계된 언어이기 때문이다. 그래

it-eldorado.tistory.com

 

'Language' 카테고리의 다른 글

[ python ] asyncio/coroutine/eventloop  (0) 2023.04.16
[ shell script ] set -e, set -o, set -x  (0) 2023.02.21
[ python ] python답게 코딩하기  (0) 2023.01.23
[ python ] event loop (2)  (0) 2022.05.24
[ python ] event loop (1)  (0) 2022.05.24
Comments