Подтвердить что ты не робот

Когда вы будете использовать Mutex без дуги?

Очень распространенный шаблон в Rust - Arc<Mutex<T>>, где Arc обеспечивает управление памятью, а Mutex обеспечивает безопасный многопоточный доступ к ресурсу. Что еще можно использовать вместо Arc и при каких обстоятельствах?

4b9b3361

Ответ 1

Arc, конечно, является наиболее распространенным в этом контексте, но существуют другие типы указателей, которые разрешают совместное использование. Основной (и наиболее распространенный, в остальной части Rust) один является общей ссылкой &T. Обычно это не работает с тегами std::thread::spawn 'd, потому что обычно указывает на данные, управляемые каким-то другим потоком, и, как правило, это не 'static (особенно это относится к &Mutex<T>). Однако для создания потока, который может обмениваться данными со своим родителем, можно использовать scoped thread. Например.

extern crate crossbeam;
use std::sync::Mutex;

fn main() {
    let data = Mutex::new(vec![0, 1]);

    crossbeam::scope(|scope| {
        // these run concurrently:
        let _guard = scope.spawn(|| {
            data.lock().unwrap().push(2);
        });
        data.lock().unwrap().push(3);
    });

    println!("{:?}", *data.lock().unwrap());
    // one of [0, 1, 2, 3] or [0, 1, 3, 2]
}

Тип data в замыкании, переданном на scope.spawn, на самом деле &Mutex<Vec<i32>> (так как он не имеет ключевого слова move, то закрытие использует стиль захвата по умолчанию: по ссылке).

& и Arc - это те, которые могут достичь такого рода потокобезопасного совместного использования в стандартной библиотеке/языке, но также можно писать типы указателей, которые обеспечивают поточно-безопасный обмен во внешних библиотеках.

Однако, удаляясь от шаблона Pointer<Mutex<...>>, может быть полезно, чтобы мьютекс и разделение разделялись, например. Arc<Vec<Mutex<T>>> позволяет делиться некоторым количеством Mutex<T> без необходимости Arc каждого отдельно, или, может быть, нужно иметь некоторую абстракцию вокруг Mutex, и поэтому оберните ее в struct:

struct Wrapped {
    data: Mutex<T>
}
impl Wrapped {
    // fancy methods that abstract over `data.lock()`
}

Вероятно, тогда можно увидеть Arc<Wrapped> (или какой-нибудь другой указатель, который разрешает совместное использование).