15. 요약 및 핵심 참조 카드 🟡
학습 목표:
- 비동기 Rust의 핵심 개념을 한눈에 볼 수 있는 **참조 카드(Cheat Sheet)**를 제공합니다.
- 상황별 최적의 도구(채널, 뮤텍스, 런타임 등) 선택 가이드를 제시합니다.
- 자주 발생하는 에러 메시지와 그에 대한 해결책을 정리합니다.
- 다음 단계로 나아가기 위한 추천 학습 리소스를 소개합니다.
🧠 비동기 멘탈 모델 (Mental Model)
| 개념 | 핵심 설명 |
|---|---|
async fn | 컴파일러에 의해 '상태 머신(열거형)'으로 변환되는 퓨처 구현체 |
.await | 현재 태스크를 멈추고 내부 퓨처가 Ready가 될 때까지 기다림 |
| 실행기(Executor) | 준비된 퓨처를 poll()하고, 쉴 때는 OS와 협력해 잠드는 무한 루프 |
| 웨이커(Waker) | "데이터 왔으니 나를 다시 폴링해!"라고 실행기를 깨우는 초인종 |
| Pin | "이 데이터는 메모리에서 위치를 옮기면 안 된다"는 특별한 약속 |
🛠️ 상황별 도구 선택 가이드
1. 채널(Channel) 선택
mpsc(N:1): 실무에서 가장 많이 쓰임. 작업 큐나 이벤트 전달용.oneshot(1:1): 딱 한 번의 결과 응답(Response)이 필요할 때.broadcast(N:N): "모든 워커 종료!" 같은 공지사항 전파용.watch(1:N): 설정값 변경처럼 '최신 상태'만 동기화할 때.
2. 뮤텍스(Mutex) 선택
std::sync::Mutex: 락을 잡고 있는 동안.await를 하지 않을 때. (매우 짧은 연산)tokio::sync::Mutex: 락을 잡은 채로 네트워크 IO 등.await를 해야 할 때.RwLock: 읽기 요청이 압도적으로 많고 쓰기는 가끔 일어날 때.
3. 동시성 제어
tokio::join!: 고정된 몇 개의 작업을 동시에 실행할 때.tokio::select!: 여러 작업 중 가장 먼저 끝나는 것을 처리할 때.buffer_unordered(N): 스트림의 아이템을 N개씩 병렬로 처리할 때.JoinSet: 동적으로 생성되는 수많은 태스크를 관리하고 결과를 수집할 때.
🚨 트러블슈팅: 흔한 에러와 해결책
-
future is not Send- 원인:
.await하는 동안Rc,RefCell등 스레드 안전하지 않은 데이터를 들고 있음. - 해결: 해당 데이터를 블록(
{ })으로 감싸거나 드롭하여.await전에 해제하세요.
- 원인:
-
borrowed value does not live long enough(spawn 시 발생)- 원인:
tokio::spawn은 태스크가 언제 끝날지 몰라 참조 데이터를 허용하지 않음. - 해결:
Arc를 쓰거나 데이터를 **clone()**하여 태스크 안으로 소유권을 넘기세요.
- 원인:
-
프로그램이 아무 반응 없이 멈춤
- 원인: 실행기를 블록했거나(Sync Sleep 등), 웨이커 호출을 잊었을 가능성이 큼.
- 해결: 블로킹 코드를 찾거나
tokio-console로 멈춘 태스크를 추적하세요.
📚 추천 학습 리소스
- Tokio 공식 튜토리얼: 가장 정석적인 실습 가이드
- Crust of Rust: async/await: 내부 구조를 파헤치는 딥다이브 영상 (Jon Gjengset)
- Actors with Tokio: 상태가 있는 서비스를 설계하는 실전 패턴 (Alice Ryhl)
비동기 Rust 교육 가이드 끝 성공적인 비동기 개발을 기원합니다! 🚀