Python과 비동기 프로그래밍: asyncio

Python과 비동기 프로그래밍: asyncio


목차

  1. 서론
  2. 비동기 프로그래밍이란?
    1. 비동기 프로그래밍의 필요성
    2. 동기 vs 비동기
  3. asyncio 소개
    1. asyncio란 무엇인가?
    2. asyncio의 주요 개념
  4. 개발 환경 설정
  5. 기본 asyncio 사용법
    1. 이벤트 루프
    2. 코루틴
    3. 태스크
  6. 고급 asyncio 기능
    1. Future 객체
    2. 비동기 I/O
    3. 타임아웃 설정
  7. 실습 예제: 비동기 웹 스크래핑
  8. 결론
  9. 추천 태그

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. 실습 예제: 비동기 웹 스크래핑

다음은 asyncioaiohttp를 사용하여 여러 웹 페이지를 동시에 스크래핑하는 예제입니다.


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의 기본 개념과 사용법을 설명하고, 실습 예제를 통해 비동기 프로그래밍을 실제로 적용하는 방법을 살펴보았습니다.

다음 이전