겁 없는 동시성

안전하고 효율적으로 동시성 프로그래밍을 다루는 것은 러스트의 또 다른 주요 목표 중 하나입니다. 동시성 프로그래밍 (concurrent programming), 즉 프로그램의 서로 다른 부분이 독립적으로 실행되는 것과, 병렬 프로그래밍 (parallel programming), 즉 프로그램의 서로 다른 부분이 동시에 실행되는 것은 더 많은 컴퓨터가 여러 개의 프로세서를 활용함에 따라 그 중요성이 커지고 있습니다. 역사적으로, 동시성 및 병렬 컨텍스트에서의 프로그래밍은 어렵고 에러를 내기 쉬웠습니다: 러스트는 이를 바꾸기를 희망합니다.

초기에 러스트 팀은 메모리 안전을 보장하는 것과 동시성 문제를 방지하는 것은 다른 방법으로 해결돼야 하는 별개의 도전 과제라고 생각했습니다. 시간이 흘러 러스트 팀은 소유권과 타입 시스템이 메모리 안전성 동시성 문제를 관리하는 것을 돕기 위한 강력한 도구들의 집합이라는 사실을 발견했습니다! 소유권과 타입 검사를 지렛대 삼음으로써, 많은 동시성 에러는 런타임 에러가 아닌 컴파일 타임 에러가 됩니다. 따라서 런타임 동시성 버그가 발생하는 정확한 환경을 재현하는 시도에 많은 시간을 쓰게 되는 것이 아니라, 부정확한 코드가 컴파일되지 않고 문제점을 설명하는 에러가 나타납니다. 결과적으로 잠재적으로 프로덕션에 배포된 이후가 아니라 작업을 하는 동안에 여러분의 코드를 고칠 수 있습니다. 우리는 러스트의 이러한 측면에 겁 없는 동시성 (fearless concurrency) 이란 별명을 지어 주었습니다. 겁 없는 동시성은 미묘한 버그가 없으면서 새로운 버그 생성 없이 리팩터링하기 쉬운 코드를 작성하도록 해줍니다.

노트: 간결성을 위해서 동시성 및/또는 병렬성이라는 정확한 표현 대신 많은 문제를 동시성이라고 지칭하겠습니다. 만일 이 책이 동시성 및/또는 병렬성에 대한 것이었다면 더 정확하게 말했을 것입니다. 이번 장에서는 동시성이라는 단어가 사용될 때마다 마음속으로 동시성 및/또는 병렬성 을 대입해 주세요.

많은 언어가 동시성 문제를 다루기 위해 제공하는 해결책에 대해 독단적입니다. 예를 들어, 얼랭 (Erlang) 은 메시지-패싱 (message-passing) 동시성을 위한 우아한 기능을 가지고 있지만 스레드 간에 상태를 공유하는 방법은 모호합니다. 고수준 언어의 경우 추상화를 위해 일부 제어권을 포기함으로써 얻을 수 있는 이점이 있기 때문에 가능한 해결책 중 일부만을 제공하는 것은 고수준 언어의 합리적인 전략입니다. 하지만 저수준 언어는 주어진 상황 내에서 최고의 성능을 갖는 해결책을 제공하고 하드웨어 대한 추상화가 적을 것으로 기대됩니다. 따라서 러스트는 여러분의 상황과 요구사항에 적합한 방법으로 문제를 모델링하기 위한 다양한 도구들을 제공합니다.

이번 장에서 다루게 될 주제들입니다:

  • 스레드를 생성하여 여러 조각의 코드를 동시에 실행시키는 방법
  • 채널들이 스레드 간에 메시지를 보내는 메시지-패싱 동시성
  • 여러 스레드가 어떤 동일한 데이터에 접근할 수 있는 상태-공유 (shared-state) 동시성
  • 러스트의 동시성 보장을 표준 라이브러리가 제공하는 타입은 물론 사용자 정의 타입으로 확장하는 SyncSend 트레이트