Python Asynchronous Programming


 비동기 프로그래밍( Asynchronous Programming in Python )

비동기 프로그래밍 개요(Overview of Asynchronous Programming)

비동기 프로그래밍은 I/O 작업(네트워크, 파일 시스템 등)과 같이 시간이 오래 걸리는 작업을 효율적으로 처리할 수 있는 방법입니다. 비동기 코드는 실행이 블로킹되지 않으며, 다른 작업이 완료될 때까지 기다리지 않고 다른 작업을 계속 수행할 수 있습니다. Python에서 비동기 프로그래밍을 위해 asyncio 모듈을 주로 사용합니다.

asyncioawait 키워드

Python의 asyncio 모듈을 사용하여 비동기 함수를 정의할 수 있습니다. async def로 비동기 함수를 정의하고, await 키워드를 사용하여 비동기 함수를 호출합니다.

import asyncio

async def say_hello():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

# 이벤트 루프 실행
asyncio.run(say_hello())

위 예제에서 say_hello 함수는 비동기 함수로 정의되었습니다. asyncio.sleep(1)은 1초 동안 비동기적으로 대기하는 함수입니다. asyncio.run()을 사용하여 이벤트 루프를 실행하고 비동기 함수를 호출합니다.

비동기 함수 병렬 실행(Running Multiple Asynchronous Functions Concurrently)

여러 비동기 함수를 병렬로 실행하려면 asyncio.gather()를 사용할 수 있습니다.

import asyncio

async def task1():
    print('Task 1 start')
    await asyncio.sleep(2)
    print('Task 1 end')

async def task2():
    print('Task 2 start')
    await asyncio.sleep(1)
    print('Task 2 end')

async def main():
    await asyncio.gather(task1(), task2())

asyncio.run(main())

위 예제에서는 task1task2가 병렬로 실행됩니다. task1이 2초 동안 대기하는 동안 task2가 1초 동안 대기한 후 종료됩니다. asyncio.gather()는 여러 비동기 함수를 동시에 실행하고 모두 완료될 때까지 기다립니다.

비동기 I/O 작업(Asynchronous I/O Operations)

비동기 프로그래밍은 특히 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, 'https://example.com')
        print(html)

asyncio.run(main())

위 예제에서는 aiohttp 라이브러리를 사용하여 비동기적으로 웹 페이지를 가져옵니다. fetch 함수는 주어진 URL에서 데이터를 가져와서 텍스트로 반환합니다. main 함수에서 비동기 HTTP 클라이언트 세션을 생성하고 fetch 함수를 호출합니다.

비동기 큐(Asynchronous Queue)

비동기 큐를 사용하여 프로듀서-컨슈머 패턴을 구현할 수 있습니다.

import asyncio

async def producer(queue):
    for i in range(5):
        await asyncio.sleep(1)
        item = f'item {i}'
        await queue.put(item)
        print(f'Produced {item}')

async def consumer(queue):
    while True:
        item = await queue.get()
        if item is None:
            break
        print(f'Consumed {item}')
        await asyncio.sleep(2)

async def main():
    queue = asyncio.Queue()
    await asyncio.gather(producer(queue), consumer(queue))
    await queue.put(None)

asyncio.run(main())

위 예제에서 producer 함수는 1초마다 아이템을 생성하여 큐에 추가합니다. consumer 함수는 큐에서 아이템을 꺼내어 처리합니다. main 함수에서 producerconsumer를 비동기적으로 실행하고, 모든 작업이 완료되면 큐에 None을 추가하여 consumer를 종료합니다.

비동기 이벤트 핸들링(Asynchronous Event Handling)

비동기 프로그래밍은 이벤트 기반 시스템에서도 유용합니다.

import asyncio

async def handle_event(event):
    await event.wait()
    print('Event has been set!')

async def main():
    event = asyncio.Event()
    asyncio.create_task(handle_event(event))
    await asyncio.sleep(2)
    event.set()

asyncio.run(main())

위 예제에서는 asyncio.Event를 사용하여 이벤트를 생성하고 비동기 함수 handle_event가 이벤트가 설정될 때까지 대기합니다. main 함수에서 2초 후에 이벤트를 설정하여 handle_event를 트리거합니다.

이와 같이, Python의 비동기 프로그래밍을 통해 효율적인 비동기 작업을 수행할 수 있습니다. asyncio 모듈은 비동기 함수 정의, 병렬 실행, 비동기 I/O 작업, 큐 및 이벤트 핸들링을 위한 강력한 도구를 제공합니다.


Leave a Reply

Your email address will not be published. Required fields are marked *