STUDY/Rust

Rust - 20. 동시성, 병렬성

sinawi95 2024. 3. 24. 20:14
728x90

동시성은 항상 읽을때마다 얼추 이해는 되는것 같은데 직접 쓸땐 또 다른건지...

겁 없는 동시성(fearless concurrency)

  • 왜 겁이 없을까? 동시성을 쓰려면 겁이 없어야하나? 아니면 러스트와 함께라면 겁이 없어지나?

1. Thread

연산을 여러스레드로 나눠서 수행하면 성능을 향상시킬수 있음.

  • 아래 조건들만 피한다면.
  • race condition, 특정 데이터에 동시에 접근하려하는것
  • dead lock, 모두 다 기다리고 있는 것
  • 그 외 순서가 명확하지 않아 생기는 자잘한 버그들

따라서 싱글 스레드와 멀티스레드는 다른 구조를 생각해야됨

스레드 관련 트레이트

  • thread::spawn - 스레드 생성
    • 반환값은 joinHandle 임
    • join() 메서드를 사용하면 다른 스레드가 종료될때까지 대기함
  • thread::sleep - 해당 명령을 실행한 스레드를 잠시 멈추게함

 

2. Message Passing

'메모리를 공유하여 통신하지 마세요; 그 대신, 통신하여 메모리를 공유하세요.' - Go 언어  

std::sync::mpsc::channel (mpsc: multiple producer, single consumer)

  • 동시성을 달성하기 위한 표준라이브러리
  • 스레드 간 데이터 전송
  • 반환 값 튜플 (tx, rx)
    • tx: 송신 단말
      • send() 메서드: 송신
    • rx: 수신 단말
      • recv() 메서드: 수신, 메인스레드 실행 블록
      • try_recv() 메서드: 수신, 블록하지 않는대신 Result<T,E> 반환

 

3. 공유 상태 동시성

여러 스레드가 동일한 데이터에 접근할수 있는 상태 공유(shared-state) 동시성

Mutex<T>: Mutual Exclusive

  • 스마트 포인터. RefCell<T>와 비슷하게 내부 가변성을 제공함
  • Rc<T>대신 Arc<T> (Atomic Reference Counter)를 사용해야함
    • Rc는 싱글 스레드에서만 사용하는 것을 가정하고 만들었기때문에 멀티 스레드를 쓰면 어떤 동작을 할지 모름
    • Arc를 사용하면 멀티 스레드에서도 안전함을 보장함

Mutex 사용규칙

  1. 데이터를 사용하기 전에 락을 걸어야함
  2. 데이터의 사용이 끝나면 락을 풀어야함

 

4. 확장 가능한 동시성

std::marker

  • Send 트레이트: 스레드 사이에서 소유권 이동을 허용함
  • Sync 트레이트: 여러 스레드의 접근을 허용함

https://doc.rust-kr.org/ch16-00-concurrency.html