Rust의 await

Nilesh Katuwal 2022년8월18일
Rust의 await

이 기사에서는 Rust에서 await의 의미를 배웁니다.

Rust의 await

async-await는 일시 중지하고 런타임에 제어를 넘긴 다음 중단된 부분에서 실행을 재개할 수 있는 기능을 작성하는 기술입니다. 일반적으로 이러한 일시 중지는 I/O를 기다리는 데 사용되지만 다양한 용도로 사용할 수 있습니다.

async-await는 JavaScript나 C#에서 익숙할 것입니다. 그러나 Rust의 기능 구현에는 몇 가지 중요한 변경 사항이 있습니다.

async-await를 활용하려면 fnasync fn으로 바꿔야 합니다.

async fn new_fxn() -> u32 { .. }

기존 함수와 달리 async fn 호출은 즉각적인 효과가 없습니다. 대신 future를 반환합니다.

계산이 일시 중단되고 실행 대기 중입니다. .await 연산자를 사용하여 future 실행:

async fn second_fxn () {
    let future = new_fxn();

    let result: u32 = future.await;
    ...
}

이 예제는 Rust와 다른 언어 간의 첫 번째 차이점을 보여줍니다. 우리는 future 대신 future.await를 씁니다. 이 구문은 Rust의 ?와 더 잘 상호작용합니다. I/O에서 흔히 볼 수 있는 오류 전파 연산자.

future.await?라고 쓸 수 있습니다. 허물을 짊어지고 많은 결과를 기다리다. 또한 체인 방식을 고통 없이 할 수 있는 이점이 있습니다.

await라는 용어는 비동기 함수의 컨텍스트 내에서만 사용할 수 있으며 비동기 함수만 대기할 수 있습니다.

Rust의 미래는 느슨합니다. 기본적으로 첫 번째 투표가 수행되기 전에는 아무 것도 하지 않습니다. 당신이 미래기다릴 때, 그것은 조사됩니다.

예를 들어, 프로그램 시작 시 future를 반환하지만 프로그램이 끝날 때까지 await하지 않는 함수를 호출하는 경우 실제 요청은 await 때까지 실행되지 않습니다.

예시:

use std::thread;
use tokio::time::{sleep, Duration};
use futures::future;

#[tokio::main]
async fn main(){
    let mut await_demo = Vec::new();

    for count in 1..=5
    {
        await_demo.push(tokio::spawn(async move{
            println!("Start the thread {count}, id= {:?}", thread::current().id());
            sleep (Duration::from_millis(5000)).await;
            println!("end the thread {count}, id = {:?})", thread::current().id());
        }));
    }
    future::join_all (await_demo).await;
}

먼저 5개의 futures(5개의 async 블록)가 생성되며, 각 futuresleep future를 생성하고 이에 대해 await를 호출합니다. 이 미래는 동시에 존재합니다.

각 블록은 await 앞과 뒤에 스레드 ID를 표시합니다.

출력:

Standard Output
Start the thread 1, id= ThreadId(2)
Start the thread 3, id= ThreadId(2)
Start the thread 4, id= ThreadId(2)
Start the thread 5, id= ThreadId(2)
Start the thread 2, id= ThreadId(3)
end the thread 2, id = ThreadId(2))
end the thread 3, id = ThreadId(3))
end the thread 1, id = ThreadId(3))
end the thread 4, id = ThreadId(3))
end the thread 5, id = ThreadId(3))