Rust의 Async/Await 이해하기
James Reed
Infrastructure Engineer · Leapcell

Rust 비동기 프로그래밍에서의 Async/.await
async/.await는 동기식 스타일로 비동기 코드를 작성할 수 있게 해주는 Rust 내장 언어 기능입니다.
예제를 통해 async/.await 키워드를 사용하는 방법을 배워봅시다. 시작하기 전에 futures 패키지를 소개해야 합니다. Cargo.toml 파일을 수정하고 다음 내용을 추가하세요:
[dependencies] futures = "0.3"
비동기 Future 생성을 위한 async 사용
간단히 말해, async 키워드는 다음 유형의 Future를 만드는 데 사용할 수 있습니다:
- 함수 정의:
async fn - 블록 정의: `async {}
예를 들어, async 함수는 다음과 같습니다:
async fn hello_world() { ... }
async 키워드는 함수 프로토타입을 수정하여 Future 트레잇 객체를 반환합니다. 그런 다음 실행 결과를 새 Future로 래핑하여 반환하며, 이는 대략 다음과 동등합니다:
fn hello_world() -> impl Future<Output = ()> { async { ... } }
참고:
async블록은 익명의Future트레잇 객체를 구현하며,Future-구현 제너레이터인Generator를 캡슐화합니다.Generator는 본질적으로 상태 머신 역할을 합니다.async블록 내의 작업이Poll::Pending을 반환하면 제너레이터는yield를 호출하여 실행을 포기합니다. 다시 시작되면 제너레이터는 모든 코드가 완료될 때까지 실행을 계속하며, 이는 상태 머신이Complete상태로 들어가Poll::Ready를 반환하여Future실행이 완료되었음을 신호합니다.
async로 표시된 코드 블록은 Future 트레잇을 구현하는 상태 머신으로 변환됩니다. 현재 스레드를 차단하는 동기 호출과 달리, Future가 차단 작업을 만나면 현재 스레드의 제어권을 포기하고 다른 Future의 실행 결과를 기다립니다.
A Future needs to run on an executor. For example, block_on is an executor that blocks the current thread:
// block_on은 지정된 Future가 실행을 완료할 때까지 현재 스레드를 차단합니다. // 이 접근 방식은 간단하고 직접적이지만, 다른 런타임 실행기는 동일한 스레드에 여러 Future를 스케줄링하기 위해 join을 사용하는 것과 같이 더 정교한 동작을 제공합니다. use futures::executor::block_on; async fn hello_world() { println!("hello, world!"); } fn main() { let future = hello_world(); // Future를 반환하므로 아직 출력되지 않습니다. block_on(future); // Future를 실행하고 완료될 때까지 기다립니다. 그러면 "hello, world!"가 출력됩니다. }
다른 비동기 Future 완료를 기다리기 위한 await 사용
위의 main 함수에서는 block_on 실행기를 사용하여 Future가 완료될 때까지 기다렸으므로 코드가 동기식으로 보였습니다. 하지만 다른 async fn 내에서 async fn을 호출하고 후속 코드를 실행하기 전에 완료를 기다려야 하는 경우는 어떻게 될까요? 예를 들어:
use futures::executor::block_on; async fn hello_world() { // async 함수 내에서 다른 async 함수를 직접 호출하는 것 - 작동할까요? hello_cat(); println!("hello, world!"); } async fn hello_cat() { println!("hello, kitty!"); } fn main() { let future = hello_world(); block_on(future); }
여기서 hello_world async 함수 내에서 먼저 다른 async 함수 hello_cat을 호출한 다음 `

