Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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());
}

Обратите внимание, что есть blanket-реализация impl<T: Send> Sync for Mutex<T>.

This slide should take about 14 minutes.
  • Mutex в Rust выглядит как коллекция из одного элемента — защищаемых данных.
    • Невозможно забыть взять мьютекс перед доступом к защищаемым данным.
  • Из &Mutex<T> можно получить &mut T, взяв блокировку. MutexGuard гарантирует, что &mut T не переживёт удерживаемую блокировку.
  • Mutex<T> реализует и Send, и Sync тогда и только тогда, когда T реализует Send.
  • Аналог с блокировкой чтения-записи: RwLock.
  • Почему lock() возвращает Result?
    • Если поток, который держал Mutex, запаниковал, Mutex становится «отравленным» (poisoned), чтобы сигнализировать, что защищаемые данные могут находиться в несогласованном состоянии. Вызов lock() у отравленного мьютекса завершается ошибкой PoisonError. Вы всё равно можете вызвать into_inner() у ошибки, чтобы восстановить данные.