Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

유한 채널(Bounded channels) vs 무한 채널(Unbounded channels)

지금까지 우리는 **무한 채널(Unbounded channels)**을 사용해 왔습니다. 메시지를 보내고 싶은 만큼 계속 보낼 수 있고, 채널은 그 모든 메시지를 담기 위해 알아서 공간을 늘렸죠.

하지만 다중 생산자 단일 소비자(MPMC) 환경에서는 이게 문제가 될 수 있습니다. 만약 생산자(Producer)가 소비자(Consumer)가 처리하는 속도보다 더 빠르게 메시지를 큐(queue)에 넣으면 어떻게 될까요? 채널은 멈추지 않고 늘어나 결국 시스템의 모든 메모리를 다 써버릴 수도 있습니다.

실제 상용 시스템(Production)에서는 무한 채널을 거의 사용하지 않는 것이 원칙입니다. 항상 **유한 채널(Bounded channels)**을 사용하여 큐에 쌓일 수 있는 메시지 개수에 상한선을 두어야 합니다.

유한 채널(Bounded channels)

유한 채널은 정해진 용량(capacity)을 가집니다. sync_channel 함수를 호출할 때 0보다 큰 용량 값을 전달하여 만들 수 있습니다.

use std::sync::mpsc::sync_channel;

// 용량이 10인 유한 채널 생성 let (sender, receiver) = sync_channel(10);

이때 receiver의 타입은 이전과 같은 Receiver<T>이지만, senderSyncSender<T>라는 새로운 인스턴스가 됩니다.

메시지 보내기

SyncSender를 통해 메시지를 보낼 때는 상황에 따라 두 가지 메서드를 선택할 수 있습니다.

  • send: 채널에 빈 공간이 있다면 메시지를 큐에 넣고 Ok(())를 반환합니다. 만약 채널이 가득 찼다면, 공간이 생길 때까지 현재 스레드를 차단(block)하고 기다립니다.
  • try_send: 채널에 공간이 있으면 메시지를 넣고 Ok(())를 반환합니다. 하지만 채널이 가득 찼다면 기다리지 않고 즉시 Err(TrySendError::Full(value))를 반환합니다. 이때 value는 보내려고 했던 메시지입니다.

역압력(Backpressure)

유한 채널을 사용하는 가장 큰 장점은 바로 **역압력(Backpressure)**을 제공한다는 점입니다. 소비자가 처리 속도를 따라가지 못할 때 생산자의 속도를 강제로 늦추게 만드는 것이죠.

역압력은 시스템 전체로 퍼져나가 전체 아키텍처에 안정성을 더해줍니다. 이를 통해 사용자의 갑작스러운 요청 폭주로 시스템 전체가 마비되는 것을 방지할 수 있습니다.

Exercise

The exercise for this section is located in 07_threads/09_bounded