본문 바로가기

프로그래밍언어/Python

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

반응형

■ Synchronous vs Asynchronous

  - Synchronous programming (동기 프로그래밍)

    : 주어진 task들을 순차적으로 실행하는 프로그래밍 방식. 하나의 작업이 수행중이면 그 다음 작업은 수행 완료까지 대기한다.

  - Asynchronous programming (비동기 프로그래밍)

    : task들을 병렬적으로 수행하는 프로그래밍 방식. 먼저 실행된 작업이 완료되지 않아도 다음 작업이 대기하지 않고 수행된다.

 

 

■ Event Loop

이벤트 루프는 작업들을 루프(반복문)를 돌면서 하나씩 실행시키는 역할을 합니다. 만약 실행된 작업이 특정한 데이터를 요청하고 응답을 기다려야 한다면, 이 작업은 다시 이벤트 루프에 통제권을 넘겨줍니다. 통제권을 받은 이벤트 루프는 다음 작업을 실행하게 됩니다. 그리고 응답을 받은 순서대로 멈췄던 부분부터 다시 통제권을 가지고 작업을 마무리합니다.

 

 

■ Coroutine

코루틴(Coroutine)은 파이썬에서 async를 통해서 생성된 비동기 함수 객체로 코루틴은 응답이 지연되는 부분에서 이벤트 루프에 통제권을 줄 수 있으며, 응답이 완료되었을 때 멈추었던 부분부터 기존의 상태를 유지한 채 남은 작업을 완료할 수 있는 함수를 의미합니다. 파이썬에서 코루틴이 아닌 일반적인 함수는 서브루틴(Subroutine)이라고 합니다.

 

 

asyncio

  - async/await 문법을 사용하여서 cpu 작업과 I/O를 병렬적으로 처리하여 비동기 프로그래밍을 가능하도록 하는 파이썬 라이브러리

  - 파이썬에서 병렬 처리를 지원하는 프레임워크들의 기반이 된다.

 

  - async

    : 비동기 함수를 생성하는 키워드이다. 기존의 함수 선언 키워드인 def 앞에 async 키워드를 붙여서 비동기 함수를 생성한다.

      async 키워드를 통해서 생성된 비동기 함수를 coroutine이라고 한다.

 

  - await

    : 비동기 함수를 호출하는 키워드이다. 비동기 함수, coroutine을 일반 함수와 같이 호출하는 경우 coroutine 객체를 반환한다.

    await 키워드를 통해서 호출해야지 비동기 함수를 실행시킬 수 있다.

 

async def async_func():
    pass

async def run_async_func():
    await async_func()

 

 

  - asyncio.get_event_loop(): 현재의 이벤트 루프를 반환하는 함수.

    async로 선언되지 않은 일반 함수에서 비동기 함수를 호출하기 위해서는 event loop를 사용해야한다.

 

  - loop.run_until_complete(future): future (Future의 인스턴스)가 완료할때까지 이벤트 루프를 실행시킵니다.

    실행한 결과, future의 결과를 반환합니다.

 

  - asyncio.Future: 비동기 연산의 최종결과를 나타내는 객체입니다.

 

import asyncio

async def async_func():
    pass
    
loop = asyncio.get_event_loop()		# 이벤트 루프를 정의한다.
loop.run_until_complete(async_func())	# 비동기 함수 - async_func를 호출한다.
loop.close()				# 이벤트 루프를 종료한다.

 

 

  - asyncio.gather(): 여러 함수를 동시에 호출할 때 사용한다.

 

loop.run_until_complete(asyncio.gather(coroutine_1(),
                                          coroutine_2()))

 

 

- asyncio.run(): 간단하게 비동기 함수를 호출하는 함수이다. 파이썬 버전 3.7 이상부터 사용 가능하다.

- asyncio.wati(): 여러개의 함수를 리스트에 담아서 호출할 수 있다.

 

async def start_coroutine():
    await asyncio.wait([                          
        coroutine_1(),
        coroutine_2()
    ])
    
asyncio.run(start_coroutine())

 

 

<reference>

- Python 3.9.4 Documentation: 이벤트 루프

- [python] 비동기 프로그래밍

- [파이썬] asyncio로 비동기 처리하기

- 파이썬과 비동기 프로그래밍 #2, 파이썬에서 비동기 프로그래밍 시작하기

- 파이썬 코딩 도장: 47.10 asyncio 사용하기

반응형