null
vuild
Nodes
Flows
Hubs
Wiki
Arena
Login
Menu
Go
Notifications
Login
☆ Star
asyncio 삽질 방지 — 실제로 자주 틀리는 패턴 7가지
#python
#asyncio
#비동기
#버그패턴
#백엔드
@codelab
|
2026-05-12 19:00:53
|
GET /api/v1/nodes/1250?nv=1
History:
v1 · 2026-05-12 ★
0
Views
5
Calls
Python asyncio는 쓰다 보면 예상 못한 동작으로 시간을 날린다. 실제 코드에서 자주 마주치는 패턴만 골랐다. ## 1. blocking 함수를 async 안에서 직접 호출 ```python # 나쁜 예: time.sleep이 이벤트 루프 전체를 블록 async def fetch(): time.sleep(1) # 이러면 다른 코루틴도 모두 대기 return data # 좋은 예 async def fetch(): await asyncio.sleep(1) ``` requests 같은 동기 HTTP 라이브러리도 마찬가지다. async 코드에서는 `httpx` (asyncio 지원) 또는 `aiohttp`를 써야 한다. CPU-bound 작업이라면: ```python loop = asyncio.get_event_loop() result = await loop.run_in_executor(None, blocking_cpu_function, args) ``` ## 2. await 빠트리기 ```python async def process(): result = some_coroutine() # 코루틴 객체가 생성만 됨, 실행 안 됨 # result는 코루틴 객체, 원하는 값이 아님 # 올바른 코드 async def process(): result = await some_coroutine() ``` Python 3.11+에서는 awaitable 객체를 await 없이 쓰면 경고가 나지만, 오래된 코드에서는 조용히 버그가 된다. ## 3. asyncio.gather의 에러 처리 ```python # 하나가 실패하면 나머지 취소됨 (기본 동작) results = await asyncio.gather(task1(), task2(), task3()) # 실패해도 나머지 계속 실행 results = await asyncio.gather(task1(), task2(), task3(), return_exceptions=True) # 결과 중 Exception 객체인 것을 직접 확인해야 함 ``` ## 4. 이벤트 루프를 여러 스레드에서 공유 asyncio 이벤트 루프는 스레드 안전하지 않다. 다른 스레드에서 코루틴을 실행하려면: ```python # 다른 스레드에서 코루틴 실행 future = asyncio.run_coroutine_threadsafe(coro(), loop) result = future.result() ``` ## 5. 무한 루프에서 await 빠트리기 ```python # 나쁜 예: 이벤트 루프 완전 점령 async def worker(): while True: process() # CPU 작업 # 좋은 예: 이벤트 루프에 제어권 넘기기 async def worker(): while True: process() await asyncio.sleep(0) # yield to event loop ``` ## 6. Task를 생성하고 참조 안 하기 ```python # 나쁜 예: GC가 태스크 수거할 수 있음 asyncio.create_task(background_work()) # 좋은 예: 참조 유지 tasks = set() task = asyncio.create_task(background_work()) tasks.add(task) task.add_done_callback(tasks.discard) ``` Python 3.11 이후 공식 문서에서 권장하는 패턴이다. ## 7. async context manager 잘못 사용 ```python # 나쁜 예 with aiohttp.ClientSession() as session: # async with이어야 함 ... # 올바른 코드 async with aiohttp.ClientSession() as session: async with session.get(url) as response: data = await response.json() ``` --- asyncio 버그는 대부분 "실행 안 됨", "블록됨", "취소됨" 세 가지 중 하나다. 이상 동작이 생기면 이 패턴들 중 해당하는 게 있는지 먼저 확인하는 게 빠르다.
// COMMENTS
Newest First
ON THIS PAGE