[Python] 비동기 처리와 asyncio

비동기 처리

  • 호출된 함수의 실행이 다 끝나지 않았어도 호출한 함수에게 return 하며 백그라운드에서 실행된다. 이후 함수 작업이 다 끝났을 때 호출한 함수에 작업이 끝났음을 통보한다.

  • 입출력과 관련된 일을 수행할 때 CPU는 대기하고하고 다른 장치들이 작업을 수행하고 있다. 이때, 쉬는 CPU의 유휴시간을 줄여 프로그램의 퍼포먼스를 높이는 것이 비동기 처리의 목적이다.


asyncio 라이브러리

  • asyncio는 파이썬에서 비동기 프로그래밍이 가능한 표준 라이브러리이다.

async & await

  • 기존 def 함수의 키워드 앞에 async 키워드를 붙여 비동기 함수를 생성한다.

    async def func():
     return
  • await 는 비동기 함수를 호출하는 키워드이다. 일반 함수를 호출하는 것처럼 비동기 함수를 호출하면 코루틴 객체를 반환한다.

  • corutine 객체말고 함수의 return 값을 반환하기 위해서는 await 키워드를 사용해야 한다. 이 키워드는 특정 객체가 끝날 때까지 기다리는 역할을 한다.

    import asyncio
     
     async def ffcc(i):
        print(i)
        return i
    
     a = ffcc(3)
     print(a)

Corutine & Subroutine

  • 코루틴은 파이썬에서 async을 통해 생성된 비동기 함수 객체이다.

  • 이벤트 루프에 통제권을 부여해 작업이 대기 혹은 지연되는 부분에서 다음 작업을 진행 시킬수 있으며 다시 응답을 받았을 때 기존상태를 유지한 채 멈췄던 부분부터 작업을 수행할 수 있는 함수이다.

  • 코루틴 아닌 일반적인 함수는 서브루틴이라고 한다.


event loop

  • 이벤트 루프는 작업들을 루프를 돌면서 순차적으로 실행시키는 역할을 한다.

  • 특정 작업이 데이터를 요청하고 대기한다면, 이벤트 루프에 통제권을 넘겨주며 이벤트 루프는 루프 내의 다음 작업을 실행하게 된다.

  • 대기하던 작업이 완료되었다는 응답을 받으면 다시 멈췄던 부분부터 다시 통제권을 가지고 작업을 수행한다.

  • asyncio.get_event_loop():
    현재의 이벤트 루프를 반환하는 함수이다. (이벤트 루프를 정의한다.)
    async로 선언되지 않은 일반 함수에서 비동기 함수를 호출하기 위해서는 event loop를 사용해야 한다.

  • loop.run_until_complete(future):
    future(Future의 인스턴스)가 완료할 때까지 이벤트 루프를 실행(async함수를 실행)시킨다.
    future의 결과를 반환한다.

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

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

    loop.run_until_complete(asyncio.gather(coroutine_1(),coroutine_2()))
  • asyncio.run():
    간단하게 비동기 함수를 호출하는 함수이다. 파이썬 3.7 이상부터 사용 가능하다.

  • asyncio.wait():
    여러개의 함수를 리스트에 담아서 호출한다.

    async def start_coroutine():
       await asyncio.wait([                          
           coroutine_1(),
           coroutine_2()
       ])
       
    asyncio.run(start_coroutine())
  • loop.close():
    이벤트 루프를 종료한다.

  • await asyncio.sleep(1)
    특정 시간동안 대기하는 비동기 함수이다. 따라서 `await 키워드와 함께 사용한다.


동기함수에서 async 함수 호출하기

  • event loop를 사용하여 호출하기

    async def ffcc(i):
       print(i)
       return i
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(ffcc(3))
    loop.close()
    
    # 출력결과: 3

async 함수에서 async 함수 호출하기

  • await 키워드를 사용한다.

    async def ffcc(i):
       print(i)
       return i
    
     async def ffbb():
       a = await ffcc(3)
       print(f"a: {a}")
    
     loop = asyncio.get_event_loop()
     loop.run_until_complete(ffbb())
     loop.close()
     
     #출력 결과:
     #3
     #a: 3



Reference

좋은 웹페이지 즐겨찾기