По сути, вы хотите позаимствовать объект у заблокированного и оставить его после разблокирования вмещающего его объекта.
Non-Stati c заимствования в этом случае невозможны, потому что это небезопасно, например , любая другая нить может отбросить владельца объекта, который вы ранее заимствовали .
Согласно вашей логике c, внутренняя locks
должна быть разделена между другими потоками, чтобы безопасно обернуть mutexes
с Arc
.
struct Bucket {
locks: HashMap<String, Arc<Mutex<()>>>,
}
И это возвратит ссылку на атомы c внутренних мьютексов.
//previously get_guards
fn get_mutexes(&mut self, key: impl Into<String>) -> Vec<Arc<Mutex<()>>> {
let lock = self.locks.entry(key.into()).or_default();
vec![lock.clone()]
}
Вы можете просто заблокировать все необходимые мьютексы следующим образом:
let mutexes = bucket.lock().unwrap().get_mutexes("key"); // locks(borrows bucket's guard) temporarily in here
let guards: Vec<MutexGuard<'_, ()>> =
mutexes.iter().map(|guard| guard.lock().unwrap()).collect();
Пожалуйста, посмотрите полный код на детская площадка