•
비동기 처리 기본 개념
◦
async 키워드
▪
비동기 함수(코루틴) 정의용
▪
호출 시 즉시 실행되지 않고, 이벤트 루프에 의해 관리됨
◦
await 키워드
▪
비동기 함수 내에서 다른 비동기 작업의 완료 대기용
▪
await 뒤의 코루틴이 완료되어야 이후 코드 실행
•
이벤트루프 개념
◦
비동기 작업 스케줄링 및 실행의 핵심
◦
모든 코루틴, 태스크, 콜백 등을 관리
◦
이벤트루프를 통해 비동기 함수들이 효율적으로 병행 실행됨
•
Python의 asyncio 라이브러리
◦
asyncio.run()
▪
이벤트루프 생성 → 코루틴 실행 → 루프 종료
▪
간단하게 비동기 프로그램 실행 가능
◦
asyncio.gather()
▪
여러 코루틴을 동시에 실행하고 결과를 모음
▪
모든 작업이 완료될 때까지 대기
◦
asyncio.run_in_executor()
▪
동기 함수를 비동기 환경에서 실행
▪
CPU-bound 또는 I/O-bound 동기 작업을 별도의 스레드/프로세스에서 실행
◦
asyncio.to_thread() (Python 3.9 이상)
▪
기존 동기 함수를 간편하게 비동기적으로 실행
•
이벤트루프 관련 함수
◦
asyncio.get_event_loop()
▪
현재 이벤트루프 반환 (없으면 새로 생성)
▪
Python 3.7 이하와 일부 상황에서 사용
▪
250311_2129_glory : 디콘사업때 이것을 주로 많이 씀
◦
asyncio.get_running_loop()
▪
현재 실행 중인 이벤트루프 반환 (코루틴 내부에서만 호출 가능)
▪
이벤트루프가 반드시 실행 중인 경우에 안전하게 접근
•
asyncio.get_running_loop() 사용 예시
◦
예시 코드:
import asyncio
async def task():
loop = asyncio.get_running_loop() # 현재 실행 중인 이벤트루프 획득
print("현재 이벤트루프:", loop)
await asyncio.sleep(1)
return "작업 완료"
async def main():
result = await task()
print(result)
asyncio.run(main())
Python
복사
▪
코루틴 내부에서 get_running_loop()를 호출하여 현재 이벤트루프에 접근
▪
비동기 작업 실행 도중 이벤트루프 정보를 확인 가능
•
이벤트루프의 역할 및 활용
◦
코루틴, 태스크, 콜백 등 비동기 작업의 실행 관리
◦
이벤트 루프를 직접 제어하여 실행 흐름을 세밀하게 조정 가능
◦
비동기 작업 추가, 스케줄링, 실행 완료 대기 등을 수행
•
종합 예시: 다양한 비동기 처리 기법 통합
◦
예시 코드:
import asyncio
import time
from concurrent.futures import ThreadPoolExecutor
# 동기 작업 (블로킹 작업)
def blocking_task(duration):
time.sleep(duration)
return f"{duration}초 후 동기 작업 완료"
# 비동기 코루틴: await 사용, asyncio.get_running_loop() 활용
async def async_task(task_id, duration):
loop = asyncio.get_running_loop() # 현재 이벤트루프 접근
print(f"Task {task_id}: 이벤트루프 사용 - {loop}")
await asyncio.sleep(duration)
return f"Task {task_id} - {duration}초 후 비동기 작업 완료"
# 비동기 코루틴: 동기 작업을 run_in_executor로 실행
async def async_with_executor(task_id, duration, executor):
loop = asyncio.get_running_loop()
print(f"Task {task_id} (executor): 이벤트루프 사용 - {loop}")
result = await loop.run_in_executor(executor, blocking_task, duration)
return f"Task {task_id} (executor): {result}"
async def main():
# asyncio.gather를 통한 병렬 실행 예시
tasks = [
async_task(1, 1),
async_task(2, 2)
]
results_async = await asyncio.gather(*tasks)
print("asyncio.gather 결과:", results_async)
# ThreadPoolExecutor를 이용한 동기 작업 비동기 실행
with ThreadPoolExecutor() as executor:
tasks_executor = [
async_with_executor(3, 1, executor),
async_with_executor(4, 2, executor)
]
results_executor = await asyncio.gather(*tasks_executor)
print("run_in_executor 결과:", results_executor)
asyncio.run(main())
Python
복사
▪
코드 구성 설명
•
async_task: 일반적인 비동기 작업, asyncio.sleep()로 비동기 대기 후 결과 반환
•
async_with_executor: 동기 함수 blocking_task를 run_in_executor를 통해 비동기적으로 실행
•
asyncio.get_running_loop()를 사용하여 각 코루틴 내에서 현재 이벤트루프 정보 출력
•
asyncio.gather()를 사용하여 여러 작업을 병렬로 실행 후 결과 집계
•
요약
◦
async/await
▪
코루틴 정의 및 비동기 작업 대기 기법
◦
이벤트루프
▪
비동기 작업 전체를 관리, 실행 스케줄링
◦
asyncio.get_running_loop()
▪
실행 중인 이벤트루프를 안전하게 획득
◦
다양한 비동기 처리 기법
▪
asyncio.gather, run_in_executor, to_thread 등을 활용하여 효율적인 비동기/동시성 프로그래밍 구현 가능
안녕하세요
•
관련 기술 문의와 R&D 공동 연구 사업 관련 문의는 “glory@keti.re.kr”로 연락 부탁드립니다.
Hello 
•
For technical and business inquiries, please contact me at “glory@keti.re.kr”