Rust에서 스레드와 Mutex로 전역 변수 안전하게 공유하기
Rust에서는 여러 스레드가 동시에 데이터를 다룰 경우, **경쟁 상태(Race Condition)**를 피하기 위해
Mutex
를 자주 사용합니다. 아래 예제는 100개의 스레드가 하나의 전역 변수
counter
를 안전하게 1씩 증가시키는 코드입니다.use std::thread;
use std::sync::Mutex;
//Mutex 는 여러 스레드가 공유자원에 동시에 접근하지 못하도록 막는 기법
//Mutex 는 잠금(lock)와 해제(unlock)의 두 가지 상태가 존재
static counter: Mutex<i32> = Mutex::new(0); // counter를 전역변수로 정의
fn inc_counter() {
// lock을 걸고 접근 권한을 획득함
//unwrap()은 lock 실패 시 패닉을 발생시킴.
let mut num = counter.lock().unwrap();
*num = *num + 1; // 자원에 접근하려면 *키워드를 사용한다.
} // inc_counter를 벗어나는 순간 counter는 unlock됩니다.
fn main() {
let mut thread_vec = vec![];
// _ 는 변수 이름이 정의되어야 할 부분에서 변수명을 생략할 때 사용한다.
for _ in 0..100 {
let th = thread::spawn(inc_counter);
thread_vec.push(th);
}
//각 스레드가 끝날 때까지 기다림.
for th in thread_vec {
//join()을 하지 않으면 메인 함수가 먼저 끝날 수도 있음.
th.join().unwrap();
}
// 마지막으로 counter의 값을 lock으로 가져와 출력.
println!("결과: {}", *counter.lock().unwrap());
}
/*실행결과
결과: 100
*/
핵심 포인트
-
Mutex<i32>
를 사용해 여러 스레드가 동시에 안전하게 공유 자원에 접근 가능 -
lock().unwrap()
으로 lock을 획득하고, 해제는 스코프 종료 시 자동 -
join()
으로 메인 스레드가 하위 스레드를 기다림
왜 Mutex가 필요한가?
스레드가 동시에 값을 수정하면 예상치 못한 오류가 발생할 수 있습니다.
Mutex
는 이런 충돌을 방지하는 락(lock) 메커니즘을 제공합니다.
댓글 없음:
댓글 쓰기