본문 바로가기
IT/Python

Python - asyncio 비동기 함수 코루틴에 대해서 알아보기

by 큰공 2021. 11. 11.
728x90
반응형

 

들어가며

 코딩 알고리즘 중 동기방식 (synchronous) / 비동기방식 ( asynchronous ) 에 대해서 알아보고, Python 에서 이를 어떻게 활용하고, aysncio 에 대해서 사용방법에 대해서 알아보고자합니다.

 또한, asyncio 를 통하여, 2가지 이상의 비동기 함수를 수행하는 방법에 대해서 설명하고자합니다.

 

동기? 비동기

 프로그래밍을 하다보면은 모든 일이 순차적으로 탁탁탁 빠르게 일어나면 가장 베스트하고 직관적인 프로그래밍이 될 수 있으나, 시간이 걸리는 작업은 병렬적으로 처리해서, 총 소요 시간의 소요를 당기고 싶은 요구가 생긴다.

 

 동기 (synchronous) / 비동기 (asynchrounous) 의 차이가 발생한다.

 

 동기 방식은 일을 하나만 처리할 수 있는 단순함이라고 보면된다. 먼저 들어온 명령을 수행하는 동안 아무것도 하지 않고, 그 명령이 수행되기 전까지 아무것도 처리하지 않는다.

 비동기 방식은 하나의 명령을 끝마치기까지 다른 누군가의 피드백이 필요하거나, 특정 시간이 소요된다면 그 남는 시간 동안 다른 일을 병렬적으로 수행 하는 방식이다.

 동기 / 비동기에 대한 설명은 다른 부분에도 많으므로 간략하게 설명하고 넘어가자.

 

코루틴 ( Coroutine )

코루틴은 실행을 일시중단(suspend)하고 재개(resume)할 수 있도록 하여 비선점형 멀티태스킹(non-preemptive multitasking)을 위한 서브루틴을 일반화하는 컴퓨터 프로그램 구성 요소이다.

코루틴은 협력 작업(Cooperative task), 예외, 이벤트 루프, 반복자, 무한 목록 및 파이프와 같은 프로그램 구성 요소를 구현하는데 적합하다.

 

 

 코루틴의 정의를 보아도, 뭔가 팍 와닿지 않는다. 그 의미를 파헤쳐 보면, "Cooperation Functions" 협력 함수!?

이다.  일단, "함수" 이다. 들어오는 인자가 있고, 나가는 리턴값이 있다. "Cooperation" 을 좀 더 유하게 이해해서 말하면, "비동기" 라고 할 수 있다. 협력을 해야 하니, 병렬로 처리가 가능해야 한다.

 

 쉽게 코루틴을 얘기 하면,

 

"비동기 방식으로 호출 될 수 있는 함수"

 

asyncio

 https://docs.python.org/ko/3/library/asyncio.html

 

asyncio — 비동기 I/O — Python 3.10.0 문서

 

docs.python.org

 파이썬 공식 문서 "asyncio" 에 대한 설명이다.

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

 aysncio 는"Python 에서 코루틴을 구현하기 위한 라이브러리" 이다.

 비동기 방식으로 처리하기 위해서는 내부적으로 테스크들을 병렬적으로 처리하기 위한, "스케쥴러" 가 필요하고, 비동기 방식의 여타 프로그래밍의 편리성을 위하여 aysncio 키워드로 이 함수가 비동기 방식의 함수 이다를 나타낸다.

 

asyncio 비동기 함수 1개 사용하기

import asyncio

async def async_func1():
    print ("Hello coinpipe!!")

async_func1()

쉽게, async 키워드를 이용하여, 비동기 함수를 하나 생성하고, 해당 함수를 호출하였다.

async 키워드를 앞에 붙인 함수는 일반 함수처럼 호출이 불가능한다. 비동기 함수는 이벤트 루프을 통한 스케쥴링 실행이 필요하기 때문이다.

RuntimeWarning: coroutine 'async_func1' was never awaited
  async_func1()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
import asyncio

async def async_func1():
    print ("Hello coinpipe!!")

# async_func1() # 에러
asyncio.run(async_func1()) #정상 수행

 정상적으로 print 가 되었음을 확인할 수 있다.

 

 

asyncio 비동기 함수 2개 사용하기

 비동기 함수를 사용하는 목적이 2개의 함수를 병렬적으로 사용하기 위해서 이므로, 2개의 비동기 함수를 수행해보도록 하자.

import asyncio

async def async_func1():
    while True:
        print ("Hello coinpipe!!")
        await asyncio.sleep(3)

async def async_func2():
    while True:
        print ("Hello bigball!!")
        await asyncio.sleep(2)

async def main():
    await asyncio.gather(
        async_func1(),
        async_func2()
    )

asyncio.run(main())

 무한 루프 속에서 Hello coinpipe 는 3초 마다 한번씩 출력하고, Hello Bigball은 2초마다 한번씩 출력하는 코드이다.

 

 비동기 함수 async_func1, 2를 각각 asyncio.gather의 인자로 넘겨주면, 비동기 함수 2개를 마치 멀티스레드를 구현한것처럼 동작이 가능하다.

 

 

 

 

728x90
반응형

댓글