2023년 6월 업데이트
안녕하세요. SQLER의 코난 김대우입니다.
이번 강좌에서는, Python 중급 강좌 - 9. 비동기 작업(Asynchronous operations): asyncio를 진행토록 하겠습니다.
SQLER에서 진행되는 전체 Python / 머신러닝 강좌 목록
코드를 실행하기 위해서는, vscode에서 새로운 파일을 만들고 실행하시면 됩니다.
예를 들어, 9_asyncio.py를 생성하고 코드를 실행합니다.
TL;DR
Python은 오랫동안 실행하는 작업을 비동기식으로 수행하기 위한 기능을 제공하며 asyncio는 async/await 기반 비동기 작업을 실행하기 위한 라이브러리입니다. asyncio를 사용하여 웹 요청이나 복잡한 데이터 처리와 같은 외부 리소스와 관련된 작업을 비동기/효율적으로 처리할 수 있습니다.
Python 중급 강좌 - 9. 비동기 작업(Asynchronous operations): asyncio
네, Python 중급 강좌의 마지막 내용인 비동기 작업입니다. 마지막 과정까지 오시느라 수고 많으셨습니다.
이름만 들어도 약간 어려울 것 같고 괜히 복잡해 보이는 Asynchronous 작업이지만, Python에서는 이 비동기 처리를 쉽게 작업 가능합니다. 지난 강좌와 마찬가지로, 차근차근 코드로 진행할 테니까요, 같이 비동기 처리에 대해 살펴보시죠.
Python과 비동기(Asynchronous) 작업
Python은 오래 실행되는 작업을 비동기적으로 관리하기 위한 여러 옵션을 제공합니다. asyncio는 async/await를 포함하는 비동기 작업을 실행하기 위한 핵심 라이브러리입니다.
동시성과 병렬처리는 모든 언어에서 다뤄지는 주제입니다. 대부분의 개발 언어는 이러한 처리를 위한 기능을 제공하며, Python 도 마찬가지로 훌륭한 비동기 처리 기능들을 제공하고 있습니다.
Javascript 쪽 관련 개발을 해본 경험이 있다면, 잘 알고 계실 거에요. 특정 웹 호출 작업이나, Network 처리 또는 복잡한 데이터 처리와 같은 작업은 시간이 오래 걸리는 작업입니다.
대부분의 작업이 외부 리소스에서 주로 처리되고, 요청 후 "기다리는" 시간이 오래 걸리는 문제가 있었죠.
네, 오늘날 대부분의 웹 호출 작업이 이러한 상황에 놓이게 됩니다. 그럼 실제 시나리오를 코드로 실행해 보시죠.
동기(Synchronous) 작업
이 예제는 전형적인 동기화 작업 패턴입니다. (timeit은 깨알같이 훌륭한 시간측정 모듈로, 작업 소요시간을 쉽게 측정 가능 가능한 timer 기능을 제공합니다.)
from timeit import default_timer import requests def load_data(delay): print(f'Starting {delay} second timer') text = requests.get(f'http://httpbin.org/delay/{delay}').text print(f'Completed {delay} second timer') def run_demo(): start_time = default_timer() two_data = load_data(2) three_data = load_data(3) elapsed_time = default_timer() - start_time print(f'The operation took {elapsed_time:.2} seconds') def main(): run_demo() main()
코드에서 보시는 것처럼 http://httpbin.org/ 웹서비스는 delay라는 기능을 제공해, 요청을 보내면 일정 초(second) 이후 응답을 리턴하는 API를 제공합니다. 이 코드에서는 load_data(2)와 load_data(3)이라는 함수를 호출해, 2초 대기 후 응답, 3초 대기 후 응답을 받아 출력해 보통 5초 이상이 소요되는 결과를 보실 수 있습니다.
느끼시는 것처럼, 요청-"대기"-요청-"대기" 이런 전형적인 동기화 작업이 순차적으로 이루어지게 되죠.
이러한 task blocking상황을 어떻게 비동기적인 호출을 이용해 효율적으로 해결할 수 있을까요?
비동기(Asynchronous) 처리 작업
비동기 처리를 Python에서 수행하기 위해 먼저 aiohttp 패키지를 설치합니다.
다음 명령을 수행해 aiohttp를 conda 환경에 설치합니다.(Python 버전 3.5 이상이 필요합니다.)
pip install aiohttp
아래 비동기 처리 코드를 실행합니다.
from timeit import default_timer import aiohttp import asyncio async def load_data(session, delay): print(f'Starting {delay} second timer') async with session.get(f'http://httpbin.org/delay/{delay}') as resp: text = await resp.text() print(f'Completed {delay} second timer') return text async def main(): # 타이머 시작 start_time = default_timer() # 하나의 세션 생성 async with aiohttp.ClientSession() as session: # 작업을 설정하고 실행 two_task = asyncio.create_task(load_data(session, 2)) three_task = asyncio.create_task(load_data(session, 3)) # 다른 프로세싱 시뮬레이션 await asyncio.sleep(1) print('Doing other work') # value 값들을 가져오기 two_result = await two_task three_result = await three_task # 결과 출력 elapsed_time = default_timer() - start_time print(f'The operation took {elapsed_time:.2} seconds') asyncio.run(main())
실행하면, 결과가 약 3초 조금 후 처리가 완료되는 것을 확인 가능합니다. 앞의 동기화 작업과 비교해 보면, 거의 동시에 진행되고, 3초 걸리는 작업의 결과와 함께 결과가 도착한 것을 확인 가능합니다. 그럼 Python이 어떻게 처리하는지 코드를 단계별로 같이 살펴보시죠.
Python의 비동기 처리 코드 리뷰
비동기 처리를 위해서는
- 비동기 처리를 위한 세션(session) 생성
- session을 이용해 task 생성
- task로 작업을 async로 실행
과정을 통해 처리됩니다. 코드를 단계별로 보면,
... # session을 async로 생성하고, async with aiohttp.ClientSession() as session: ... # task를 생성해 session 인스턴스를 실행할 함수에 넘깁니다. two_task = asyncio.create_task(load_data(session, 2)) ... # 실행하는 load_data 함수에서는 이렇게 session을 이용해 HTTP GET 처리를 async로 처리합니다. async with session.get(f'http://httpbin.org/delay/{delay}') as resp:
이렇게 비동기 작업을 non-blocking 처리 가능합니다.
Python에서 이런 비동기로 처리하는 다양한 패턴이 존재합니다. 이러한 웹 요청 외에 다양한 분야에서도 여러 코드를 테스트하면서 수행해 보시면 비동기 처리로 여러 작업들을 수행하실 수 있을 것입니다.
Python 중급강좌를 마치고, 이후 Python 인공지능/머신러닝 강좌 계획
Python 초급강좌에 이어, Python 중급강좌까지 수고 많으셨습니다. 중급강좌까지 마무리하셨다면, 이제 어느 Python코드를 만나도 당황하거나 두려워하지 않으셔도 될 겁니다. 짧은 강좌들이었지만, 꼭 필요한 주제들을 담았고 이제 새로운 Python의 기능을 만나도 조금만 검색하면 어렵지 않게 사용방법이나 코딩 패턴을 보고 개발하실 수 있을 겁니다.
Python 강좌에 대해 궁금하신 사항은 언제든지, 개발자 커뮤니티 SQLER.com - 파이썬 & 오픈소스 개발 질문과 답변 게시판에 올려 주시면 도움드리도록 하겠습니다. SQLER 커뮤니티에서는 계속해서 다양한 Python 강좌를 진행할 예정이니 많은 관심 부탁 드려요.
이어지는 머신러닝 강좌는, SQLER의 개발자 커뮤니티 SQLER.com - 머신러닝 & AI 개발자 Tip & 강좌에서 진행될 예정입니다. 많은 관심 부탁 드립니다.
수고하셨습니다.
파이썬 강좌 책 구매
강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다.
책구매 링크: 챗GPT와 함께하는 파이썬 & 머신러닝 코딩 마스터
참고자료
개발자 커뮤니티 SQLER.com - Python 무료 강좌 - 기초, 중급, 머신러닝