본문 바로가기

파이선 (python)

[Python] 비동기(Async) 방식 프로그램을 구현해보자

728x90

[ 동기 / 비동기 차이점 ]

* 동기 방식 함수를 선언할 때는 함수명 앞에 'def'를 사용한다.

def print_test():
	print("Test")

* 비동기 방식 함수의 경우 함수명 앞에 'async def'를 사용한다.

* 아래와 같은 비동기 방식으로 만들어진 함수를 코루틴(coroutine)이라고 부른다.

async def print_test():
	print("Test")

 

[ 비동기 함수 사용방법 ]

* 각기 다른 기능을 하는 비동기 함수 2개를 만들고 동시에 실행하는 코드를 작성한다.

- function_1 : 0.5초 간격으로 숫자 0부터 8까지 순차적으로 출력하는 비동기 함수 

- function_2 : 1초 간격으로 문자 A부터 H까지 순차적으로 출력하는 비동기 함수

- main : 비동기 함수  function_1 과  function_2를 동시에 실행하는 비동기 함수 

* time.sleep(1) 함수는 대기 시간 동안 CPU가 다른 일을 처리하지 않지만, asyncio.sleep(1)의 경우 대기하는 동안 CPU가 다른 일을 처리할 수 있다.

* async def(비동기  함수)는 일반적으로 async로 선언된 다른 비동기 함수 내에서 'await' 키워드를 붙여서 호출해야 한다

* 만약 async 로 선언되지 않은 동기 함수(def) 내에서 비동기 함수를 호출할 경우에는 asyncio 라이브러리의 이벤트 루프를 이용해야 한다.

import asyncio

# 0.5초 간격으로 0 부터 8 까지 순차적으로 출력하는 비동기 함수
async def function_1():
    for i in range(9):
        await asyncio.sleep(0.5)    # 0.5초 대기(비동기)
        print(i)

# 1초 간격으로 A 부터 H 까지 순차적으로 출력하는 비동기 함수
async def function_2():
    for letter in 'ABCDEFGH':
        await asyncio.sleep(1)      # 1초 대기(비동기)
        print(letter)

# 2개의 함수를 동시에 실행하는 비동기 함수
async def main():
    await asyncio.gather(function_1(), function_2())

# main 함수를 비동기 방식으로 실행
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

* 위 소스 코드를 'test_asyncio_01.py'로 저장한 후 실행하면 아래와 같이 숫자는 0.5초 간격으로 출력되고 문자는 1초 간격으로 출력되는 것을 볼 수 있다.

 

* 위 소스 코드에서 async로 선언되지 않은 동기 함수(def) 내에서 비동기 함수를 호출할 경우에는 asyncio 라이브러리의 이벤트 루프를 이용하였으나, python 3.7 이상에서는 ' asyncio.run(main()) '로 간단히 비동기 함수 main()을 호출 가능하다.

import asyncio

# 0.5초 간격으로 0 부터 8 까지 순차적으로 출력하는 비동기 함수
async def function_1():
    for i in range(9):
        await asyncio.sleep(0.5)    # 0.5초 대기(비동기)
        print(i)

# 1초 간격으로 A 부터 H 까지 순차적으로 출력하는 비동기 함수
async def function_2():
    for letter in 'ABCDEFGH':
        await asyncio.sleep(1)      # 1초 대기(비동기)
        print(letter)

# 2개의 함수를 동시에 실행하는 함수
async def main():
    await asyncio.gather(function_1(), function_2())

# main 함수를 비동기 방식으로 실행 (python 3.7 이상)
asyncio.run(main())

* 위 소스 코드를 'test_asyncio_02.py'로 저장한 후 실행하면 아래와 같이 동일한 결과가 나오는 걸 볼 수 있다.

* 불필요한 안내 메시지도 사라진다.