[Python] Asyncio_01

atesi·2022년 9월 1일
0

asyncio

목록 보기
1/7

이 포스트는 BBC R&D Cloudfit team팀의 James Weaver의 Python의 비동기 기능에 관한 투고를 번역하며 이해하기 위해 올린 글입니다.

asyncio는 async/await 구문을 사용하여 동시성 코드를 작성하는 라이브러리이다.

Python 코드에서 asyncio를 사용해도 멀티스레드 되지 않고 여러 Python 명령어를 동시에 실행하지 않으며 GIL을 위배할 수 없다.

Python은 기본적으로 reference counting을 바탕으로 GC(Garbage Collection)를 수행한다. Python 객체의 reference count는 객체가 참조될 때마다 증가하고 객체의 참조가 해제될 때 감소한다. 객체의 reference count가 0이 되면 객체의 메모리 할당이 해제된다.

여러 쓰레드가 Python 인터프리터를 동시에 실행할 수 있게 두면 각 객체의 참조 횟수가 올바르게 관리되지 못할 수도 있고, 이에 따라 GC가 제대로 동작하지 않을 수도 있다. 이를 Race Condition이라 하는데 해결을 위해 python은 Mutex로 GIL을 이용한다.

GIL은 한 쓰레드가 Python 인터프리터를 실행하고 있을 때는 다른 쓰레드들이 Python 인터프리터를 실행하지 못하도록 막아 race condition을 해결한다.

프로그램은 IO 바운드 코드를 실행할 때 현재 수행 중인 작업이 다른 곳에서 무언가를 기다리는 것이기 때문에 CPU가 아무 작업도 하지 않는 데 많은 시간을 보내는 것이 일반적이다.

이러한 대기 중에 프로그램에 대기 중인 작업에 의존하지 않은 작업이 있다는 것을 알게 된다. asyncio는 코드를 구조화하여 linear single-threaded code의 하나("coroutine")가 어떤 일이 일어나기를 기다리고 있을 때 다른 부분이 CPU를 넘겨받아 사용할 수 있도록 설계한다.

Coroutine

대부분의 프로그래밍 언어는 "Subroutine" 호출 모델을 가진다. 함수가 호출될 때마다 호출하는 이 모델에서의 실행은 해당 함수의 시작 부분으로 이동한 다음 해당 함수의 끝에 도달할 때까지 계속된다. 이후에 함수에 대한 호출은 처음부터 다시 시작되는 독립 실행이다.

코드 실행의 대체 모델인 "Coroutine"이라는 코드 실행 모델이 있다. 이 호출 모델에서는 메서드("Coroutine")가 호출자에게 실행을 다시 이동시킨다. 반환 대신 제어를 "Yield" 할 수 있다. 코루틴이 "Yield" 하면 실행이 호출된 직후 지점으로 돌아가지만 코루틴에 대한 향후 호출이 처음부터 다시 시작되지 않고 대신 실행이 가장 최근에 중단된 곳에서 계속된다.

EventLoops

acyncio에서는 스레드당 하나의 스택만 가지고 있지 않다. 대신 각 스레드에는 Eventloops라는 객체가 있다. 이벤트루프에는 Tasks라는 객체 목록이 포함되어 있고 각 작업은 단일 스택과 실행 포인터를 유지 관리한다.

이벤트 루프는 한 번에 하나의 태스크만 실제로 실행할 수 있으며 루프의 다른 태스크는 모두 일시 중지된다. 현재 실행 중인 작업은 일반(동기) Python 프로그램에서 함수를 실행하는 것처럼 정확히 계속 실행된다.

그런 다음 기다리지 않고 Task의 코드에서 control을 생성. 이벤트 루프에 실행 중인 작업을 일시 중지하고 기다려야 하는 일이 발생하면 나중에 다시 깨우도록 요청한다. 이후 이벤트루프는 다른 작업 중 하나를 선택하여 깨우고 대신 실행 작업이 된다. 또는 그들 중 무엇도 깨어날 수 없다면 기다릴 것이다.

코드 제어가 서로 다른 작업 사이를 왔다 갔다 하면서 매번 중단된 지점에서 다시 깨우는 이 실행 패턴을 "코루틴 호출"이라 한다.





참고
https://docs.python.org/ko/3/library/asyncio.html
https://bbc.github.io/cloudfit-public-docs/asyncio/asyncio-part-1
https://it-eldorado.tistory.com/159

profile
Action!

0개의 댓글