Python과 비동기 프로그래밍: asyncio
목차
- 서론
- 비동기 프로그래밍이란?
- 비동기 프로그래밍의 필요성
- 동기 vs 비동기
- asyncio 소개
- asyncio란 무엇인가?
- asyncio의 주요 개념
- 개발 환경 설정
- 기본 asyncio 사용법
- 이벤트 루프
- 코루틴
- 태스크
- 고급 asyncio 기능
- Future 객체
- 비동기 I/O
- 타임아웃 설정
- 실습 예제: 비동기 웹 스크래핑
- 결론
- 추천 태그
1. 서론
비동기 프로그래밍은 효율적인 프로그램 작성을 가능하게 하는 중요한 기법입니다. 특히 네트워크 요청이나 파일 입출력과 같은 I/O 바운드 작업에서 유용합니다. Python에서는 asyncio
모듈을 사용하여 비동기 프로그래밍을 쉽게 구현할 수 있습니다. 이번 포스팅에서는 초보 개발자도 쉽게 이해할 수 있도록 asyncio
를 사용하여 비동기 프로그래밍을 구현하는 방법을 설명하겠습니다.
2. 비동기 프로그래밍이란?
2.1 비동기 프로그래밍의 필요성
비동기 프로그래밍은 프로그램이 시간이 오래 걸리는 작업을 수행하는 동안 다른 작업을 계속할 수 있도록 합니다. 이는 프로그램의 응답성을 높이고, 자원의 효율적인 사용을 가능하게 합니다.
2.2 동기 vs 비동기
- 동기: 작업이 순차적으로 수행되며, 하나의 작업이 완료될 때까지 다른 작업이 대기합니다.
- 비동기: 작업이 동시에 수행되며, 하나의 작업이 완료되기 전에 다른 작업을 시작할 수 있습니다.
3. asyncio 소개
3.1 asyncio란 무엇인가?
asyncio
는 Python의 비동기 프로그래밍을 위한 라이브러리로, 비동기 I/O, 이벤트 루프, 코루틴, 태스크 등을 지원합니다. 이를 통해 고성능 비동기 프로그램을 쉽게 작성할 수 있습니다.
3.2 asyncio의 주요 개념
- 이벤트 루프: 비동기 작업을 관리하고 실행하는 중심입니다.
- 코루틴: 비동기 함수로,
async
키워드로 정의됩니다. - 태스크: 이벤트 루프에서 실행되는 코루틴입니다.
- Future 객체: 비동기 작업의 결과를 나타내는 객체입니다.
4. 개발 환경 설정
Python 3.4 이상 버전에서는 asyncio
가 표준 라이브러리에 포함되어 있습니다. 별도의 설치 없이 사용할 수 있습니다. Python 버전을 확인하고 최신 버전을 설치하는 것이 좋습니다.
5. 기본 asyncio 사용법
5.1 이벤트 루프
이벤트 루프는 비동기 작업을 관리하고 실행하는 역할을 합니다.
import asyncio
async def main():
print("Hello")
await asyncio.sleep(1)
print("World")
# 이벤트 루프 실행
asyncio.run(main())
5.2 코루틴
코루틴은 async
키워드로 정의된 비동기 함수입니다.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
asyncio.run(say_hello())
5.3 태스크
태스크는 이벤트 루프에서 실행되는 코루틴입니다.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
6. 고급 asyncio 기능
6.1 Future 객체
Future 객체는 비동기 작업의 결과를 나타냅니다.
import asyncio
async def set_after(fut, delay, value):
await asyncio.sleep(delay)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
loop.create_task(set_after(fut, 1, 'hello'))
result = await fut
print(result)
asyncio.run(main())
6.2 비동기 I/O
비동기 I/O는 파일 입출력과 네트워크 요청 등을 비동기로 처리합니다.
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'http://example.com')
print(html)
asyncio.run(main())
6.3 타임아웃 설정
비동기 작업에 타임아웃을 설정하여 일정 시간이 지나면 작업을 취소할 수 있습니다.
import asyncio
async def say_hello():
await asyncio.sleep(2)
print("Hello")
async def main():
try:
await asyncio.wait_for(say_hello(), timeout=1)
except asyncio.TimeoutError:
print("Timeout!")
asyncio.run(main())
7. 실습 예제: 비동기 웹 스크래핑
다음은 asyncio
와 aiohttp
를 사용하여 여러 웹 페이지를 동시에 스크래핑하는 예제입니다.
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'http://example.com',
'http://example.org',
'http://example.net'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for result in results:
print(result[:100]) # 첫 100글자만 출력
asyncio.run(main())
8. 결론
비동기 프로그래밍은 프로그램의 효율성을 높이고, 응답성을 개선하는 데 매우 유용한 기법입니다. Python의 asyncio
모듈은 비동기 프로그래밍을 쉽게 구현할 수 있도록 도와줍니다. 이번 포스팅에서는 asyncio
의 기본 개념과 사용법을 설명하고, 실습 예제를 통해 비동기 프로그래밍을 실제로 적용하는 방법을 살펴보았습니다.