네트워크·DB처럼 I/O를 기다리고 라이브러리가 비동기를 지원하면 asyncio, 동기 I/O만 제공하면 스레드, 오래 계산하는 Python CPU 작업이면 프로세스를 먼저 생각해.
비동기 코드에서 짧은 동기 I/O는 asyncio.to_thread로 보내 이벤트 루프를 막지 않고, CPU 계산은 프로세스 풀로 넘겨. 중요한 건 “끝까지 비동기”라는 구호가 아니라 어디가 얼마나 막히는지 측정하고 그 경계를 명시하는 거야.
자유 스레딩 Python이 널리 기본이 되면 CPU 선택은 달라질 수 있지만, 현재 일반 빌드에서는 GIL을 전제로 해.