Rust - Thread vs Async

숲사람·2022년 8월 19일
0

Rust

목록 보기
12/15

IO bound task vs CPU bound task

  • CPU bound task
    CPU operation을 많이 수행하는 task. 예를 들어 이미지의 크기 조정, 회전 등의 연산은 CPU bound task이다.
  • IO bound task
    I/O operation을 많이 수행하는 task. 예를 들어 서버나 database 요청, memory나 device 를 R/W하는 작업이다.

CPU는 I/O Bus보다 월등히 빠르기 때문에, 디바이스나 Bus로부터 R/W를 하기위해 오랜 시간을 기다려야 한다. 따라서 I/O bound task들은 asynchronous하게 수행/관리 되면 좋다.

Async vs threads in Rust

Rust에서 IO bound task는 async/await를 사용하는것이 더 유리하다. (의문: CPU bound task는 std::thread를 사용하는것이 적합?) Embedded환경은 I/O연산이 많기 때문에, Embedded-rust 에서 aync/await를 사용하는 이유가 바로 이것. 다만 async는 executable 바이너리 사이즈를 더 증가시킬수 있다.

Thread를 spawning하고 switching하는 작업은 시스템의 리소스를 많이 사용하는 비용이 꽤 큰 작업이다. (Thread pool library를 사용하면 조금 개선이 가능). 몇 OS는 thread의 우선순위를 설정할 수 있기 때문에, latency가 중요한 task에는 thread가 도움이 될 수 있다. 반면 연산이 많지 않은 task들은 thread보다 async를 사용하는게 바람직 하다. Thread는 비용이 크기 때문.

두개의 웹 페이지를 다운로드 하는작업을 해보자. 아래와 같이 thread를 사용하면 시스템의 자원을 불필요하게 낭비 하는것과 같다. 웹 페이지를 다운로드하는 것은 작업량이 많지 않은 작은 task이기 때문.

fn get_two_sites() {
    // Spawn two threads to do work.
    let thread_one = thread::spawn(|| download("https://www.foo.com"));
    let thread_two = thread::spawn(|| download("https://www.bar.com"));

    // Wait for both threads to complete.
    thread_one.join().expect("thread one panicked");
    thread_two.join().expect("thread two panicked");
}

async를 사용하면 굳이 thread를 사용하지 않고도 더 효율적으로 작업할 수 있다.

async fn get_two_sites_async() {
    // Create two different "futures" which, when run to completion,
    // will asynchronously download the webpages.
    let future_one = download_async("https://www.foo.com");
    let future_two = download_async("https://www.bar.com");

    // Run both futures to completion at the same time.
    join!(future_one, future_two);
}
profile
기록 & 정리 아카이브용

0개의 댓글