군침이 싹 도는 코딩

asyncio 본문

Python/Basic

asyncio

mugoori 2023. 8. 8. 10:57

파이썬에서 웹소켓 기술을 사용하기 위해서는 websockets 라는 모듈을 사용해야한다

이 모듈은 파이썬의 비동기 ( asynchronous ) 처리를 위한 asyncio 라는 표준모듈을 기반으로 개발 되었다

 

 

동기 호출과 비동기 호출 방식

 

동기 호출 방식은 일을 순차적으로 처리하는것이다

예를 들어 햄버거 세트를 주문 받으면 햄버거를 만든다 > 감자튀김을 튀긴다 > 콜라를 따른다 순으로

차례대로 일을 처리하는것을 말한다

 

비동기 호출 방식은 동기 호출 방식보다 일을 효율적으로 처리한다

햄버거 세트를 주문 받으면 감자튀김을 튀김기에 넣고 감자튀김이 튀겨지는 동안 햄버거를 만드는 식으로

어떤 일을 처리를 기다릴때 다른일을 하는것을 말한다

 

컴퓨터 작업으로 치면 데이터를 요청하고 기다리는 동안 다른작업을 수행하는식이다

이러한 특징 덕분에 비동기 호출방식이 동기 호출방식보다 처리 시간이 짧다

 

그렇지만 비동기처리 방식이 항상 동기처리 방식보다 좋은것은 아니다.

비동기 처리 방식이 동기처리 방식보다 효율적이려면 수행할 작업이 단순 연산 중심의 작업이 아닌 중간마다

쉴 수 있는 형태의 작업이어야 한다. 예를 들어 프로그램을 인터넷에서 다운로드 받고 이를 처리하는 함수들을

먼저 프로그램을 다운로드 받는 데 시간이 소요되는데 이런 작업은 비동기처리 방식을 사용하는것이 좋다

 

코루틴

파이썬에서 비동기 방식으로 호출될 수 있는 함수를 정의 하는 법

async 라는 키워드를 붙여준다 파이썬에서는 async 키워드가 있는 함수를 코루틴 ( coroutine ) 이라고 부른다

코루틴 함수는 정의하는 방법도 다르지만, 호출 역시 일반 함수와 다른 방식으로 호출한다

import asyncio 

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

async_func1()
#asyncio.run(async_func1())

# 다음과 같은 방식으로 코루틴을 일반 함수처럼 호출하면 “async_func1 was never awaited” 에러가 발생한다.

 

여러 코루틴을 잘 처리하기 위해서는 스케줄러가 필요하다 이를 이벤트 루프라고 부른다

코루틴을 처리하기전에 먼저 이벤트 루프를 만들고 코루틴의 처리가 끝난 후에는 이벤트 루프를 닫아주면 된다

이러한 역할을 간단히 처리해주는것이 asyncio 모듈의 run 함수이다

 

import asyncio 

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

loop = asyncio.get_event_loop()
loop.run_until_complete(async_func1())
loop.close()

# 이벤트 루프를 가져오고 코루틴 객체가 완료될 때까지 실행한다 그 후 이벤트 루프를 닫는다

 

 

import asyncio 

async def make_americano():
    print("Hamburger Start")
    await asyncio.sleep(3)
    print("Hamburger End")

async def make_latte():
    print("French fries Start")
    await asyncio.sleep(5)
    print("French fries End")

async def main():
    coro1 = make_hamburger()
    coro2 = make_french_fries()
    await asyncio.gather(
        coro1, 
        coro2
    )

print("Main Start")
asyncio.run(main())
print("Main End")

# 3초를 기다리기 위하여 asyncio.sleep 함수를 호출한다. asyncio.sleep 함수는 time.sleep과 비슷하게 정해진 시간(secs) 동안 대기한다. time.sleep 함수가 CPU를 점유하면서 기다리는 것과 달리 asyncio.sleep 함수는 CPU가 다른 코루틴을 처리할 수 있도록 CPU 점유를 해제한 상태로 기다린다. 즉, 어떤 코루틴이 asyncio.sleep 함수를 실행하는 순간 이벤트 루프는 다른 코루틴을 실행시킨다. asyncio.sleep 함수 역시 코루틴인데 코루틴 내에서 다른 코루틴을 호출할 때 await 구문을 사용한다. asyncio.sleep을 통해 5초동안 더 대기한 뒤 햄버거를 만드는 코루틴 객체를 생성한다

감자튀김을 만드는 객체를 생성한 뒤 햄버거와 감자튀김 만드는 코루틴을 동시에 실행한다이벤트루프를 생성하여 main 코루틴을 처리하고 이벤트 루프를 닫는다