비동기 프로그래밍( Asynchronous Programming in Python )
비동기 프로그래밍 개요(Overview of Asynchronous Programming)
비동기 프로그래밍은 I/O 작업(네트워크, 파일 시스템 등)과 같이 시간이 오래 걸리는 작업을 효율적으로 처리할 수 있는 방법입니다. 비동기 코드는 실행이 블로킹되지 않으며, 다른 작업이 완료될 때까지 기다리지 않고 다른 작업을 계속 수행할 수 있습니다. Python에서 비동기 프로그래밍을 위해 asyncio
모듈을 주로 사용합니다.
asyncio
와 await
키워드
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())
위 예제에서는 task1
과 task2
가 병렬로 실행됩니다. 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
함수에서 producer
와 consumer
를 비동기적으로 실행하고, 모든 작업이 완료되면 큐에 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 작업, 큐 및 이벤트 핸들링을 위한 강력한 도구를 제공합니다.