🚀
async/await — Rust의 비동기 프로그래밍
Future trait 기반, 런타임 선택이 자유로운 비동기 모델
JavaScript의 async/await와 문법은 비슷하지만 내부 동작이 다르다. Rust의 async fn은 Future trait을 구현하는 상태 머신으로 컴파일된다. 힙 할당도 최소화된다.
async fn fetch_data(url: &str) -> Result<String, Error> {
let response = reqwest::get(url).await?;
let body = response.text().await?;
Ok(body)
}
Rust 표준 라이브러리에는 비동기 런타임이 포함되어 있지 않다. tokio(가장 인기)나 async-std를 직접 가져다 쓴다. 이 설계 덕분에 임베디드 환경에서는 가벼운 런타임을, 서버에서는 고성능 런타임을 선택할 수 있다.
Pin과 Self-Referential Future
async 블록이 .await를 넘어서 로컬 변수의 참조를 유지하면 자기 참조(self-referential) 구조가 된다. 이걸 안전하게 다루기 위해 Pin
핵심 포인트
1
async fn은 Future trait을 구현하는 상태 머신으로 컴파일
2
.await에서 제어를 런타임에 양보(yield) — 다른 태스크 실행
3
tokio::spawn으로 비동기 태스크를 스케줄러에 등록
4
#[tokio::main]으로 런타임 초기화 + main을 async로
장점
- ✓ 제로 코스트 — Future가 상태 머신으로 컴파일, 힙 할당 최소
- ✓ 런타임 교체 가능 — tokio, async-std, smol 등
단점
- ✗ async trait이 최근까지 불안정했다 (RPITIT로 안정화 진행 중)
- ✗ Pin/Unpin 개념이 어렵다
- ✗ 라이브러리가 tokio vs async-std로 갈리는 생태계 분열
사용 사례
웹 서버(axum, actix-web) — 수천 동시 연결을 적은 스레드로 처리
HTTP 클라이언트(reqwest) — 동시 다중 요청