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

Arc<Mutex> 로 공유 상태

~12 min · concurrency, arc, mutex, shared-state

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

다른 협력 스타일은 공유 상태야: 여러 스레드가 한 데이터를 읽고 써. 위험은 뻔해 — 두 스레드가 동시에 쓰면 망가져. Rust 의 안전한 공유-가변 타입은 Arc<Mutex<T>> 야.

Mutex: 한 번에 한 스레드

Mutex<T> (mutual exclusion) 가 안쪽 값을 지켜: 스레드가 .lock() 을 불러 배타적 접근을 얻고, 첫 스레드가 풀기 전엔 다른 스레드가 락 못 해. lock 은 guard 를 반환하고; guard 통해 변형하고, guard 가 drop 되면 (스코프 끝 — 또 RAII) 락이 자동 해제돼. 락을 쥐지 않고선 데이터에 말 그대로 닿을 수 없어.

Mutex 를 공유하려고 Arc

Mutex 혼자선 owner 하나야. 여러 스레드가 닿게 하려면 Arc 로 감싸: Arc<Mutex<T>>. 각 스레드가 같은 Mutex 로의 clone 된 Arc 핸들을 얻어. Arc 가 스레드 간 소유권을 공유하고; Mutex 가 접근을 직렬화해. Smart Pointers 트랙의 Rc<RefCell<T>> 의 정확한 멀티스레드 평행이야.

Arc 가 소유권을 공유; Mutex 가 접근을 직렬화. 같이, Arc<Mutex<T>> 가 여러 스레드한테 안전한 공유-가변 접근을 줘: 공유하려고 Arc clone, 한-번에-하나 변형하려고 Mutex lock. 락 guard 의 Drop 이 자동 해제해 — unlock 까먹을 수 없어.

컴파일러가 여전히 뒤를 봐줘

락 없이 데이터를 실수로 못 읽어 — 값이 Mutex 에 살아서 .lock() 통해서만 닿거든. 그리고 Arc 없이 맨 Mutex 를 스레드 간 공유 못 해; 컴파일러가 요구해. 다른 언어에서 제일 위험한 '공유 가변 상태' 경로조차 여기선 구조적으로 race-free 야.

Code

열 스레드가 공유 카운터를 안전하게 증가·rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            let mut n = counter.lock().unwrap(); // 배타적 접근
            *n += 1;
        })); // 락 guard 가 여기서 drop -> 락 해제
    }
    for h in handles {
        h.join().unwrap();
    }

    println!("final: {}", *counter.lock().unwrap()); // 항상 10
}

External links

Exercise

5 스레드 간 공유되는 Arc<Mutex<Vec<i32>>> 를 써; 각 스레드가 자기 id 를 벡터에 push 해. 다 join 한 뒤 정렬된 벡터를 출력하고 5 개 id 가 다 있는지 확인해. push 순서는 비결정적인데 왜 최종 결과는 내용상 결정적이야?
Hint
Mutex 가 각 push 를 배타적으로 보장해서 push 가 하나도 안 잃어 — 5 개 id 다 들어가. 들어가는 순서는 비결정적 (스케줄러 의존) 이라, 결정적 표시를 위해 출력 전에 정렬하는 거야.

Progress

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

댓글 0

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

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