러스트의 표준 라이브러리에서는 멀티스레딩 안전한 작업을 위한 기본 동기화 원시 타입을 제공합니다:
AtomicBool, AtomicUsize 등) — 잠금 없이 하드웨어 수준에서의 읽기/쓰기를 지원합니다;예제:
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); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("결과: {}", *counter.lock().unwrap()); }
질문: Rust는 Mutex<T>를 사용함으로써 교착 상태(dealock)를 컴파일 단계에서 전부 방지한다고 보장하나요?
답변: 아니요. Rust는 소유권 및 차용 검사기를 통해 데이터에 대한 안전한 접근을 보장하지만, 언어 수준에서 교착 상태를 방지하지 않습니다. 교착 상태는 여러 Mutex의 잡기 순서가 어지럽거나 재귀적 잡기가 있을 때 논리적으로 발생합니다. 예:
use std::sync::Mutex; let lock1 = Mutex::new(0); let lock2 = Mutex::new(0); // 스레드 1: lock1 -> lock2, 스레드 2: lock2 -> lock1 ⇒ deadlock
역사
역사
Mutex<Option<T>>에서 RwLock<T>로 대량 마이그레이션 했습니다. writable lock은 읽기 락보다 더 오래 걸릴 수 있음을 고려하지 않았습니다. 피크 로드 기간에 이는 쓰기를 위한 대기열로 인해 처리 지연이 수십 초로 늘어나게 했습니다.역사
프로그래머들이 스레드를 아끼기 위해 Arc<Mutex<_>>를 수백 개 스레드에서 사용했습니다. 스케줄러의 미세한 작동 및 mutex 재사용으로 인해 기묘한 상호 대기가 발생했으며 성능은 5배 감소했습니다!