////

Rust Arc<Mutex> vs Arc<RwLock> — 동시성 선택 기준

읽기가 쓰기보다 현저히 많은( 10:1 이상) 동시성 데이터는 Arc<RwLock<T , 쓰기 비율이 높거나 락 구간이 짧으면 Arc<Mutex<T 가 낫다. async 컨텍스트(.await 존재)는 반드시 tokio::sync 락을 사용한다.

////

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년 현재도 표준; 코드 정확.