Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Почему именно а, а не б?
'b
, и вообще произвольный идентификатор. Лайфтаймовые параметры очень похожи на типовые параметры, недаром они находятся рядом, в одних и тех же угловых скобках.мутабельная ссылка, которая возвращается функцией access, не может действовать дольше, чем MutexGuard, из которого она получена;
error: `guard` does not live long enoughНе понимаю, как это работает, если в компилятор не знает о мьютексах ничего. Или знает?
Если все компоненты типа являются Send, то и он сам является Send, что покрывает большинство типов.Что-то тут не то, из нескольких по отдельности атомарных счетчиков можно элементарно сконструировать потоконебезопасный тип.
Ограничение Send на T означает, что T можно безопасно пересылать между потоками.
Send это немного другое. Потокобезопасный это trait Sync, а Send просто позволяет отправлять объект в другой поток
Естественно, Arc является Send, а Rc — нет.
let r0: Rc<i32> = Rc::new(1);
let r1 = r0.clone(); // клонируем указатель, счётчик ссылок увеличивается
thread::spawn(move || {
let r2 = r1.clone();
let r3 = r2.clone();
let r4 = r1.clone();
});
let r2 = r0.clone();
let r3 = r0.clone();
Можно определять «родительские» (в данном случае guard) и «дочерние» (vec), чтобы обусловить понятие «что-то живет не дольше чего-то»?
let mut guard = lock(mutex);
let vec = access(&mut guard);
guard
имеет тип MutexGuard. access принимает мутабельную ссылку на MutexGuard и возвращает ссылку на охраняемый вектор (которая присваивается vec). При этом лайфтайм, ассоциированный со ссылкой, связывается с лайфтаймом MutexGuard, потому что access определена вот так: fn access<'a, T>(guard: &'a mut MutexGuard<T>) -> &'a mut T
(ну или не статическим).
fn vecOfSize(&int size) {
return Vec::new(size);
}
fn wrong() -> &i32 {
let x = 10;
&x
}
Кажется, начинаю понимать — ссылка должна от чего-то зависеть, может от области, но если мы возвращаем ссылку, область функции уже закончилась по определению — значит остается зависеть только от какого-нибудь параметра.
Только как при этом должно выглядеть «чисто языковое» тело функции access(), чтобы компилятор понял, что &mut Vec зависит от &mut MutexGuard? Или компилятор привязывает к первому аргументу, не глядя? Или там на самом деле опять unsafe?
struct X {
x: i32
}
fn access(x: &mut X) -> &mut i32 {
&mut x.x
}
unsafe fn get(&self) -> &mut T
Нет, вывод о связи между входной и выходной ссылкой компилятор делает только на основании сигнатуры функции, игнорируя её тело
Не понимаю, как это работает, если в компилятор не знает о мьютексах ничего. Или знает?
RWLock
, похожий, например, на ReadWriteLock из джавы.
Многопоточность в Rust