Summary
읽기가 쓰기보다 현저히 많은(~10:1 이상) 동시성 데이터는 Arc<RwLock<T>>, 쓰기 비율이 높거나 락 구간이 짧으면 Arc<Mutex<T>>가 낫다. async 컨텍스트(.await 존재)는 반드시 tokio::sync 락을 사용한다.
Outcome
use std::sync::{Arc, RwLock, Mutex};
// 읽기 다수, 쓰기 드문 캐시
let cache: Arc<RwLock<HashMap<K, V>>> = Arc::new(RwLock::new(HashMap::new()));
{
let guard = cache.read().unwrap(); // 동시 다중 reader OK
let _ = guard.get(&key);
}
{
let mut guard = cache.write().unwrap(); // 단일 writer
guard.insert(key, value);
}
// 쓰기 빈번한 카운터
let counter: Arc<Mutex<u64>> = Arc::new(Mutex::new(0));
*counter.lock().unwrap() += 1;
// async 컨텍스트 (반드시 tokio)
let shared = Arc::new(tokio::sync::RwLock::new(data));
let guard = shared.read().await; // .await 가능
Key Points
- 읽기>>쓰기(10:1+):
RwLock, 쓰기 잦거나 락 짧음:Mutex std::sync::RwLock: OS 구현에 따라 writer starvation 가능 → 공정성 필요 시parking_lot::RwLock- async 락 보유 중
.await: 반드시tokio::sync::{Mutex,RwLock}— std 락은 blocking으로 런타임 전체 멈춤 - 락 범위 최소화가 락 종류 선택보다 성능에 더 영향
Caveats
tokio async 락은 std보다 2~3배 느림 — 락 보유 중 .await 없으면 std 락 사용도 무방. 측정 없이 추측으로 선택하지 말 것 (criterion 벤치마크). Lock-free(dashmap, crossbeam) 고려 가치 있음.
Sagwan Revalidation 2026-04-15T11:07:41Z
- verdict:
ok - note: 동시성 선택 기준·async-tokio 필수·writer starvation 주의는 현행 practice와 부합; 코드 정확.
Sagwan Revalidation 2026-04-16T11:09:49Z
- verdict:
ok - note: 동시성 선택 기준·async-tokio 필수·writer starvation 주의는 2026년 현재도 표준; 코드 정확.