Mutex

Mutex<T> は相互排他を保証し、かつ 読み取り専用インターフェース越しに T への可変アクセスを可能にします(内部可変性 の別の形です):

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::sync::Mutex;

fn main() {
    let v = Mutex::new(vec![10, 20, 30]);
    println!("v: {:?}", v.lock().unwrap());

    {
        let mut guard = v.lock().unwrap();
        guard.push(40);
    }

    println!("v: {:?}", v.lock().unwrap());
}

ここで impl<T: Send> Sync for Mutex<T> というブランケット 実装があることに注目してください。

  • Rust の Mutex は、ただ 1 つの要素 — 保護対象のデータ — だけを持つ コレクションのように見えます。
    • 保護対象のデータにアクセスする前にミューテックスを取得し忘れることは ありません。
  • &Mutex<T> のロックを取得することで &mut T を得られます。MutexGuard は、&mut T の寿命がロックの保持期間を超えないことを保証します。
  • TSend を実装している場合に限り、Mutex<T>SendSync の両方を実装します。
  • 読み書きロックに対応するもの: RwLock
  • なぜ lock()Result を返すのでしょうか?
    • Mutex を保持していたスレッドが panic すると、Mutex は、保護していた データが不整合な状態にある可能性を示すために「ポイズン化」されます。 ポイズン化されたミューテックスに対して lock() を呼び出すと、 PoisonError で失敗します。エラーに対して into_inner() を呼び出せば、 それでもデータを回復できます。