# 스레드 대신 async/await를 선택하는 이유

> Clean Markdown view of GeekNews topic #13994. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=13994](https://news.hada.io/topic?id=13994)
- GeekNews Markdown: [https://news.hada.io/topic/13994.md](https://news.hada.io/topic/13994.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-03-26T10:07:09+09:00
- Updated: 2024-03-26T10:07:09+09:00
- Original source: [notgull.net](https://notgull.net/why-not-threads/)
- Points: 4
- Comments: 1

## Topic Body

- Rust 커뮤니티에서 스레드는 async/await 가 할수 있는걸 다 할 수 있고 더 간단한데 왜 async/await를 선택하는가?라는 질문이 자주 보임  
- Rust는 저수준 언어로, Coroutine의 복잡성을 숨기지 않음. 이는 프로그래머가 비동기를 고려할 필요도 없이 기본적으로 비동기로 되는하는 Go와 같은 언어와 반대되는 개념  
- 똑똑한 프로그래머는 복잡성을 피하려고 노력하는데, `async`/`await`는 왜 필요한가?  
  
### 배경 알아보기   
  
- Rust는 저수준 언어임. 코드는 일반적으로 선형적이며, 한 작업이 끝나면 다른 작업이 실행됨.  
- 웹 서버와 같은 동시에 많은 작업을 실행해야 하는 경우, 선형 코드로는 문제가 발생함.  
- 초기 웹은 스레딩을 도입하여 이 문제를 해결하려고 시도함.  
- 스레드를 사용하여 동시에 여러 클라이언트를 처리할 수 있으나, 프로그래머들은 OS 공간에서 사용자 공간으로 동시성을 가져오고자 함.  
  
### 타임아웃 문제  
  
- Rust의 가장 큰 장점 중 하나는 _조합성(composability)_ 임.  
- `async`/`await`는 I/O 바운드 함수에 이 조합성을 적용할 수 있게 함.  
- 예를 들어, 클라이언트 처리 함수에 타임아웃을 추가하고자 할 때, 두 개의 조합자를 사용하여 구현할 수 있음.  
  
### 테마틱 스레드  
  
- 스레드를 사용한 예제에서 타임아웃을 구현하는 것은 쉽지 않음.  
- `TcpStream`에는 `set_read_timeout`과 `set_write_timeout` 함수가 있지만, 이를 사용하는 것은 제한적임.  
- Rust의 조합자를 사용하여 타임아웃을 프로그래밍하는 방법을 제시하지만, 이는 `TcpStream`에만 국한되고 추가 시스템 호출이 필요함.  
  
### Async 성공 사례  
  
- HTTP 생태계는 `async`/`await`를 주요 런타임 메커니즘으로 채택함.  
- `tower`는 `async`/`await`의 강력함을 보여주는 예로, 타임아웃, 속도 제한, 부하 분산 등을 제공함.  
- `macroquad`는 Rust 게임 엔진으로, `async`/`await`를 사용하여 엔진을 실행함.  
  
### Async의 이미지 개선  
  
- `async`의 이점이 널리 알려지지 않아 일부 사람들이 오해할 수 있음.  
- Rust 커뮤니티는 `async` Rust의 성능 이점을 과대평가하고 의미 있는 이점을 축소하는 경향이 있음.  
- `async`/`await`는 동기 Rust에서 수십 개의 스레드와 채널 없이는 표현할 수 없는 패턴을 간결하게 표현할 수 있는 강력한 프로그래밍 모델로 봐야 함.  
  
### GN⁺의 의견  
  
- `async`/`await`는 동시성을 처리할 때 코드의 복잡성을 증가시키지만, 동시에 많은 클라이언트를 효율적으로 처리할 수 있는 능력을 제공함.  
- 이 기사는 `async`/`await`가 단순히 성능상의 이점을 넘어서 프로그래밍 모델의 강점을 가지고 있음을 강조함.  
- Rust의 `async`/`await`는 다양한 I/O 작업에 대한 조합성을 제공하며, 이는 특히 네트워크 서비스나 웹 서버와 같은 분야에서 유용함.  
- 비판적인 시각에서 볼 때, `async`/`await`의 복잡성은 초보 개발자들에게 진입 장벽이 될 수 있으며, 이를 극복하기 위한 교육적 노력이 필요함.  
- 동일한 기능을 제공하는 다른 프로젝트로는 Node.js의 `async`/`await` 구현이나 Python의 `asyncio` 라이브러리가 있으며, 이들도 비슷한 패러다임을 제공함.  
- `async`/`await`를 도입할 때는 코드의 복잡성과 유지보수성을 고려해야 하며, 동시에 많은 클라이언트를 처리해야 하는 경우에는 이 모델이 큰 이점을 제공함.

## Comments



### Comment 24014

- Author: neo
- Created: 2024-03-26T10:07:09+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=39812969) 
- **Async/await와 단일 스레드**
  - 자바스크립트 모델처럼 단일 스레드에서의 async/await는 단순하고 잘 이해되어 있음.
  - 스레드를 사용하면 여러 CPU가 문제를 처리할 수 있고, Rust는 락 관리를 도와줌.
  - 다른 우선순위의 스레드를 가질 수 있으며, 계산에 제한이 있는 경우 필요함.
  - 멀티 스레드 async/await는 복잡함. 계산에 제한이 있는 섹션에서는 모델이 붕괴될 수 있음.
  - Rust에서 멀티 스레드 계산은 잘 작동하지 않음. 문제점으로는:
    - Futex 혼잡 붕괴: 일부 저장소 할당자에서 문제가 될 수 있음.
    - 불공정한 뮤텍스의 기아: 표준 Mutex와 crossbeam-channel 채널이 불공정함.

- **Async/await 대 스레드**
  - 비판은 복잡성에 관한 것이 아니라, 선택에 따라 생태계가 분열되고 하나가 열등해지는 것에 대한 것임.
  - Rust 생태계는 IO 작업을 하려면 전부 async/await를 사용해야 한다고 결정함.
  - Rust가 async/await 이외의 것들을 더 조합 가능한 추상화로 만들었다면 불만이 사라졌을 것임.

- **기사에 대한 문제점**
  - 웹 서버 예시 하나만 제시되었고, 스레드에 대해 잘못 해결됨.
  - 프로그래머들은 OS 스레드가 아닌 개념적, 의미적 스레드를 원함.
  - OS 스레드는 비용이 많이 들고, 우리는 저렴한 스레드를 원함.
  - 웹 서버 예시에서의 타임아웃 구현 문제점.

- **다루지 않은 순간들**
  - async/await는 단일 스레드에서 실행되므로 락이나 동기화가 필요 없음.
  - async/await에서의 오류 전파는 명확하지 않음.
  - 네트워크 I/O에서 백프레셔도 언급되어야 함.

- **취소에 관한 중요한 점**
  - 미래의 어떤 작업도 쉽게 취소할 수 있음.
  - 스레드에서의 취소는 복잡하고, 강제 스레드 중단은 신뢰할 수 없음.
  - Rust의 async 모델에서는 모든 futures에 외부에서 타임아웃을 추가할 수 있음.

- **Async/await에 대한 마케팅 같은 캠페인**
  - async/await는 기술적 실수였으며, 커뮤니티에 큰 비용을 초래함.
  - Rust는 여전히 가장 좋은 언어이지만, 이 논쟁이 영원히 이어질까 걱정됨.

- **Async/await 대 파이버**
  - Rust는 이전에 그린 스레드를 가졌었고 의도적으로 제거됨.
  - futures를 언제든지 드롭할 수 있는 능력이 큰 비용을 수반함.
  - async/await의 조합성을 칭찬하는 것은 이상함.

- **Rust의 async/await 주요 이점**
  - 스레드나 동적 메모리가 없는 상황에서도 작동할 수 있음.
  - 동시성을 사용하여 코드를 간결하게 작성할 수 있음.

- **Async/await에 대한 오해**
  - 단일 스레드에서의 동시성 메커니즘이 필요한 이유를 이해하지 못하는 사람들이 있음.
  - UI 프로그래밍, GPU와의 통신, 런타임 간 통신 등에 async/await가 유용함.

- **Async/await 대 스레드 선택 이유**
  - async/await는 클라이언트/요청/작업 상태의 메모리 사용량을 줄일 수 있음.
  - 상태 압축은 메모리 속도가 느린 현대에서 성능에 중요함.
  - async/await와 CPS는 클라이언트당 메모리 사용량을 줄이는 데 효과적임.
