- 실행을 일시 중단하고 재개할 수 있는 특수한 함수
- 네트워크 요청이나 파일 입출력 같은 I/O 바운드 작업에서 사용
- CPU가 불필요하게 대기하지 않도록, 코루틴을 사용하여 작업을 잠시 중단한 후 다른 작업을 처리 가능
def coroutine_example():
print("Coroutine initialized") # 코루틴 초기화 메시지
x = yield # 첫 번째 yield, 여기서 멈춤
print(f"Received value: x = {x}") # x가 들어오면 출력
y = yield x + 10 # 두 번째 yield, x + 10을 반환
print(f"Received another value: y = {y}") # y가 들어오면 출력
yield x + y # x와 y의 합을 반환
# 코루틴을 생성하고 초기화
coro = coroutine_example()
next(coro) # "Coroutine initialized" 출력
# 첫 번째 값 전송
result1 = coro.send(5) # 5가 x에 할당
print(result1) # 출력: 15 (x + 10의 결과)
# 두 번째 값 전송
result2 = coro.send(20) # 20이 y에 할당
print(result2) # 출력: 25 (x + y의 결과)
Coroutine initialized
Received value: x = 5
15
Received another value: y = 20
25
"yield"이 외부에서 값을 받아들이고 중간에 멈춰서, 다시 실행될 수 있는 역할을 하는 함수여서 yield 에서 대기했다가 send()로 값 전송했을 때 그 값이 x에 할당됩니다.
Python에서는
import asyncio
async def task1():
await asyncio.sleep(2)
print("Task 1 완료")
return "Task 1 결과"
async def task2():
await asyncio.sleep(1)
print("Task 2 완료")
return "Task 2 결과"
async def main():
# create_task()로 개별 Task 생성 및 실행
task1_obj = asyncio.create_task(task1())
task2_obj = asyncio.create_task(task2())
# 여러 Task를 gather()로 동시에 실행하고, 결과를 받음
results = await asyncio.gather(task1_obj, task2_obj)
print(results) # ['Task 1 결과', 'Task 2 결과'] 출력
asyncio.run(main()) # 주피터 노트북에서는 asyncio.run() 대신 await 사용
Task 2 완료
Task 1 완료
['Task 1 결과', 'Task 2 결과']
두 개의 작업을 동시에 실행하기 때문에 총 2초 안에 모든 작업이 완료됩니다.
import aiohttp
import asyncio
# 여러 URL에서 데이터를 비동기적으로 가져오는 함수
async def fetch(session, url):
# 네트워크 요청을 보내고 응답 객체를 관리
async with session.get(url) as response:
return await response.text() # 응답 데이터를 텍스트로 반환
# 메인 비동기 함수
async def main():
# 동시에 요청을 보낼 URL 목록
urls = ["http://abc.com", "http://def.org", "http://ghi.com"]
# aiohttp.ClientSession()을 사용해 네트워크 세션을 생성
async with aiohttp.ClientSession() as session:
# 각 URL에 대해 비동기적으로 데이터를 가져오는 작업을 생성
tasks = [fetch(session, url) for url in urls]
# 모든 비동기 작업을 동시에 실행하고, 결과가 모두 완료될 때까지 대기
results = await asyncio.gather(*tasks)
# 각 요청의 응답 데이터를 출력
for result in results:
print(result)
# 이벤트 루프를 실행하여 비동기 작업을 처리
asyncio.run(main())