C.W.K.
Stream
Lesson 05 of 05 · published

Send, Sync & Fearless Concurrency

~11 min · concurrency, send, sync, fearless

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

컴파일러가 데이터 레이스 없음을 어떻게 약속 할까? 두 마커 trait — SendSync — 로, 스레드 안전성을 타입 시스템에 인코딩해서. 이 트랙의 모든 게 그 위에 서 있어.

Send: 스레드 간 move 안전

타입이 다른 스레드로 소유권 이전이 안전하면 Send 야. 대부분 타입이 그래. 주목할 예외가 Rc — 비원자적 카운트가 두 스레드가 동시에 clone 하면 race 하니, RcSend아니고, 컴파일러가 스레드로 move 를 거부해. Arc (원자적) 는 Send 라, 그게 스레드 간 선택인 이유야.

Sync: 참조로 공유 안전

&T 를 스레드 간 공유해도 안전하면 타입이 Sync 야 — 여러 스레드가 동시에 참조를 들 수 있어. Mutex<T>Sync 야 (락이 동시 접근을 안전하게 함); 맨 RefCell 은 아니야 (런타임 borrow 추적이 원자적이 아니라서). 컴파일러가 이걸 자동 검사해.

Send 랑 Sync 가 'fearless' 가 강제되는 법이야. 컴파일러가 추론하는 자동 파생 마커 trait 이야: 관련 타입들이 race-safe 임을 증명할 때만 스레드 spawn 이나 참조 공유를 허용해. 틀리면 컴파일 안 돼. 보장은 규율이 아니라 — 타입 시스템이야.

거의 안 쓰지만, 항상 일하고 있어

Send/Sync 를 손으로 구현할 일은 거의 없어 — 다른 Send/Sync 타입으로 지어진 타입엔 자동 파생되거든. 근데 그게 이 트랙의 모든 예제가 실제로 안전할 때만 컴파일되는 이유야. 동시성 실수가 컴파일 안 되고 에러가 SendSync 를 언급하면, 그게 타입 시스템이 데이터 레이스를 돌기도 전에 잡은 거야.

Code

Arc 는 Send; Rc 는 아님 — 컴파일러가 강제·rust
use std::rc::Rc;
use std::sync::Arc;
use std::thread;

fn main() {
    // Arc 는 Send: 컴파일되고 race-free
    let shared = Arc::new(5);
    let a = Arc::clone(&shared);
    thread::spawn(move || println!("arc: {a}")).join().unwrap();

    // Rc 는 Send 아님. 다음은 컴파일 안 됨:
    //   let r = Rc::new(5);
    //   let r2 = Rc::clone(&r);
    //   thread::spawn(move || println!("{r2}"));
    //   error: `Rc<i32>` 는 스레드 간 안전하게 보낼 수 없음
    let _local = Rc::new(0); // Rc 는 한 스레드 안에선 완벽히 괜찮아
    println!("{_local}");
}

External links

Exercise

읽기 전용 값을 Arc 로 스레드 간 공유하고 컴파일되는 걸 확인해. 그다음 Rc 로 바꾸고 Send 에러를 전체로 읽어. 네 말로, Send bound 가 무슨 데이터 레이스를 막고, Arc 는 왜 만족하고 Rc 는 왜 안 해?
Hint
Rc 의 참조 카운트는 평범한 정수라, 두 스레드가 동시에 올리면 race 하고 망가져. Arc 는 race 못 하는 원자적 증가를 써. Send 가 정확히 이 구분을 인코딩해서, 컴파일러가 Arc 만 스레드를 넘게 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.