C
Python/비동기/Lesson 21

비동기 프로그래밍 소개

1시간·theory
Python

비동기 프로그래밍 소개

🎯 이 lesson 을 읽고 나면

이 lesson 을 다 읽고 나면 아래 3가지를 자신 있게 할 수 있습니다.

  • ✅ Python 이 AI/데이터 표준 언어가 됐는지
  • ✅ Python 3.x 기준 venv + requirements.txt 셋업
  • ✅ print / input / type / dir 4개 내장 함수

학습 목표를 체크리스트로 두고 다 답할 수 있게 되면 lesson 을 닫으세요.

async/await — 코드 + 실행 결과

async def + await = 여러 작업 동시 처리 (단일 스레드, IO 대기 효율). HTTP·DB 호출에 표준.


1. 동기 vs 비동기 — 시간 차이

python
import time

# ❌ 동기 — 순차 실행 (총 3초)
def 가져오기():
    time.sleep(1)
    return "완료"

시작 = time.time()
결과들 = [가져오기() for _ in range(3)]
print(time.time() - 시작)        # 3.0초
python
import asyncio

# ✅ 비동기 — 동시 실행 (총 1초)
async def 가져오기():
    await asyncio.sleep(1)        # 기다리는 동안 다른 작업 가능
    return "완료"

async def 메인():
    시작 = asyncio.get_event_loop().time()
    결과들 = await asyncio.gather(
        가져오기(), 가져오기(), 가져오기()
    )
    print(asyncio.get_event_loop().time() - 시작)    # 1.0초

asyncio.run(메인())

2. 핵심 키워드

키워드의미
async def비동기 함수 정의
await비동기 결과 기다림 (이 사이 다른 작업 OK)
asyncio.run()메인 진입점
asyncio.gather()여러 작업 동시

3. HTTP 호출 (실무)

python
import asyncio
import aiohttp           # pip install aiohttp

async def 가져오기(세션, url):
    async with 세션.get(url) as 응답:
        return await 응답.text()

async def 메인():
    urls = ["https://example.com", "https://python.org"]
    async with aiohttp.ClientSession() as 세션:
        결과들 = await asyncio.gather(*[가져오기(세션, u) for u in urls])
        for r in 결과들:
            print(len(r))

asyncio.run(메인())

4. 흔한 실수

python
# ❌ async 함수를 그냥 호출 — coroutine 반환 (실행 X)
결과 = 가져오기()                   # <coroutine object>

# ✅ await 필수
결과 = await 가져오기()             # 실제 실행

# ❌ 동기 sleep — 다른 작업 못 함
time.sleep(1)

# ✅ 비동기 sleep
await asyncio.sleep(1)

한 줄 요약

async def + await + asyncio.gather() — IO 대기 많은 곳 (HTTP·DB) 에서 N배 빨라짐.

💻 async/await 기본
import asyncio

# 코루틴 정의
async def say_hello(name, delay):
    await asyncio.sleep(delay)  # 비동기 대기
    print(f"Hello, {name}!")
    return f"Done: {name}"

# 순차 실행 (총 3초)
async def sequential():
    await say_hello("A", 1)
    await say_hello("B", 1)
    await say_hello("C", 1)

# 동시 실행 (총 1초)
async def concurrent():
    await asyncio.gather(
        say_hello("A", 1),
        say_hello("B", 1),
        say_hello("C", 1)
    )

# 실행
async def main():
    print("순차 실행:")
    await sequential()
    
    print("\n동시 실행:")
    await concurrent()

# 메인 실행
asyncio.run(main())

# 동기 vs 비동기 비교
# 동기: 요청1 완료 → 요청2 시작 → 요청2 완료
# 비동기: 요청1 시작 → 요청2 시작 → 둘 다 완료

💡 핵심 포인트

1. async def: 코루틴 함수 정의
2. await: 코루틴 실행 대기
3. asyncio.run(): 이벤트 루프 실행

⚠️ asyncio.run() 주의사항: 이미 실행 중인 이벤트 루프(Jupyter Notebook, FastAPI 내부 등) 안에서 asyncio.run()을 호출하면 RuntimeError가 발생합니다. 그런 환경에서는 await 코루틴을 직접 사용하거나, nest_asyncio 라이브러리를 활용하세요.

Python의 비동기 프로그래밍은 asyncio 라이브러리로 구현합니다. async def로 코루틴 함수 정의, await로 비동기 작업을 기다립니다. asyncio.gather()로 여러 코루틴을 동시 실행합니다. I/O 바운드 작업(HTTP, DB, 파일)에 효과적이며, CPU 바운드는 multiprocessing을 사용하세요. aiohttp, httpx는 비동기 HTTP 클라이언트 라이브러리입니다.

🐍 실행해보기 — 비동기 프로그래밍 소개

위 개념을 실제로 코드로 실행해보세요. 값을 바꿔가며 어떻게 동작하는지 직접 확인하는 게 가장 빠른 학습.
✏️ Python 코드
📟 콘솔 출력
▶ 실행 버튼을 눌러보세요
🐍 Pyodide로 실제 Python 실행 — 첫 실행 시 로딩 3~5초 소요

🤖 AI 에게 이렇게 요청해보세요

이 lesson 의 개념을 알면 AI 에게 구체적으로 지시할 수 있습니다. 막연한 "고쳐줘" 가 아니라 어휘를 가진 요청 — 그게 토큰 절약의 출발점입니다.

  • "이 동기 requests 호출들을 asyncio + httpx 로 병렬화해줘"
  • "이 async 코드의 예외 처리 (asyncio.gather return_exceptions) 추가해줘"

왜 이게 토큰을 줄이나

개념을 모를 땐 AI 답변을 받고도 "그게 뭐예요?" 를 다시 물어야 합니다. 그 "다시 물음" 이 토큰을 잡아먹습니다. 개념 한 번 익혀두면 대화가 한 번에 끝납니다.

먼저 읽으면 좋은 개념: 타입 힌팅
다음 추천: pytest 입문
비동기 프로그래밍 소개 - Python