[Python] Asyncio_03

atesi·2022년 9월 16일
0

asyncio

목록 보기
3/7

Future

Future객체는 awaitable유형이다.
코루틴 객체와는 다르게 await할때 코드블록을 실행하지 않는다. 대신 Future의 대상은 다른 곳에서 진행 중인 아직 완료되거나 완료되지 않은 일부 프로세스를 나타내는 것으로 생각될 수 있다.

Future를 await하면 발생하는 일

  • future가 나타내는 프로세스가 완료되어 값을 반환한 경우 await 문은 즉시 해당 값을 반환한다.
  • future가 나타내는 프로세스가 완료되어 예외를 발생하면 await문은 즉시 그 예외를 발생시킨다.
  • future가 나타내는 프로세스가 아직 완료되지 않은 경우 현재 Task는 프로세스가 완료될 때까지 일시 중지됩니다. 완료되면 위의 경우대로 작동합니다.

모든 future객체 f는 awatable 이외에도 다음과 같은 동기 인터페이스가 있다.

  • f.done()은 만약 future가 나타내는 프로세스가 완료되면 True를 반환한다.
  • f.exception()은 프로세스가 아직 끝나지 않았다면 asyncio.InvalidStateError를 발생시킨다. 만약 프로세스가 완료되면 그것의 예외를 발생시키거나 예외를 발생시키지 않고 종료된다면 None을 반환한다.
  • 만약 프로세스가 아직 끝나지 않았다면 f.result()asyncio.InvalidStateError 예외를 발생시킨다. 프로세스가 완료되면 발생한 예외를 발생시키거나 발생시키지 않고 완료되면 반환된 값을 반환.

중요한 것은 완료된 future를 아직 완료되지 않은 future로 되돌릴 수 있는 방법은 없다는 점이다. 완료될 future는 일회성 발생이다.

코루틴과 future를 구분하는 것은 중요합니다. 코루틴의 코드는 기다릴 때까지 실행되지 않습니다. future는 어쨌든 실행 중인 무언가를 나타내며, 단순히 코드가 완료될 때까지 기다렸다가 완료되었는지 확인하고, 완료되었으면 결과를 가져올 수 있도록 합니다.
매직 메서드 __await__를 구현하는 객체는 대기할 때 거의 모든 작업을 수행할 수 있습니다. 그것들은 코루틴처럼 행동하거나 Futures처럼 행동할 수 있습니다. 그들은 완전히 다른 일을 할 수 있습니다. 문제의 클래스에 대한 문서는 일반적으로 클래스의 동작이 무엇인지 명확해야 합니다.

비동기화 기능을 확장하는 새로운 라이브러리를 구현하지 않는 한 자신의 future를 만드는 일은 거의 없다. 그러나 라이브러리 함수는 종종 future를 반환한다는 것을 알게 될 것이다. 직접 future를 개척할 필요가 있는 경우는, 다음 호출과 같이 수행할 수 있다.

f = asyncio.get_running_loop().create_future()

반면에 관련 메소드인 create_task를 꽤 자주 사용할 것이다.

Task

각각의 이벤트루프는 여러 task를 포함하고 있고 실행 중인 모든 코루틴은 task내에서 task들을 수행한다. task를 생성하는 방법을 알아본다.

async def example_coroutine_function():
    ...

t = asyncio.create_task(example_coroutine_function())

create_task 메서드는 코루틴 객체를 매개변수로 사용하고 asyncio.Future에서 상속되는 Task 객체를 반환한다. 호출은 현재 스레드에 대한 이벤트 루프 내부에 작업을 생성하고 코루틴의 코드 블록 시작 부분에서 작업 실행을 시작한다. 반환된 future는 작업이 실행을 완료한 경우에만 done()으로 표시된다. 코루틴 코드 블록의 반환 값 result()은 완료될 때 future 객체에 저장될 것이다.(그리고 그것이 발생하면 예외가 catch되어 미래에 저장됩니다).

코루틴을 래핑하는 작업을 만드는 것은 동기 호출이므로 동기 또는 비동기 코드 내부를 포함하여 어디에서나 수행할 수 있다.
비동기 코드에서 수행하는 경우 이벤트 루프는 이미 실행 중이며(현재 비동기 코드를 실행 중이기 때문에) 다음에 기회가 있을 때(즉, 다음에 현재 작업이 일시 중지될 때) 새 작업을 활성화할 수 있다.
그러나 동기 코드에서 수행할 때 이벤트 루프가 아직 실행되지 않을 가능성이 있다. 수동으로 이벤트 루프를 조작하는 것은 파이썬 문서에서 권장하지 않는다. 기능을 확장하는 라이브러리를 개발하지 않는 한 asyncio동기 코드에서 작업을 생성하는 것을 피해야 한다.

동기식 스크립트에서 단일 비동기 코드를 호출해야 하는 경우 asyncio.run()을 사용할 수 있다.

profile
Action!

0개의 댓글