gpt4 book ai didi

rust - 使用它的守卫时如何避免互斥量借用问题

转载 作者:行者123 更新时间:2023-11-29 08:10:06 25 4
gpt4 key购买 nike

我希望我的结构方法以同步方式执行。我想通过使用 Mutex ( Playground ) 来做到这一点:

use std::sync::Mutex;
use std::collections::BTreeMap;

pub struct A {
map: BTreeMap<String, String>,
mutex: Mutex<()>,
}

impl A {
pub fn new() -> A {
A {
map: BTreeMap::new(),
mutex: Mutex::new(()),
}
}
}

impl A {
fn synchronized_call(&mut self) {
let mutex_guard_res = self.mutex.try_lock();
if mutex_guard_res.is_err() {
return
}
let mut _mutex_guard = mutex_guard_res.unwrap(); // safe because of check above
let mut lambda = |text: String| {
let _ = self.map.insert("hello".to_owned(),
"d".to_owned());
};
lambda("dd".to_owned());
}
}

错误信息:

error[E0500]: closure requires unique access to `self` but `self.mutex` is already borrowed
--> <anon>:23:26
|
18 | let mutex_guard_res = self.mutex.try_lock();
| ---------- borrow occurs here
...
23 | let mut lambda = |text: String| {
| ^^^^^^^^^^^^^^ closure construction occurs here
24 | if let Some(m) = self.map.get(&text) {
| ---- borrow occurs due to use of `self` in closure
...
31 | }
| - borrow ends here

据我所知,当我们从结构中借用任何东西时,在借用完成之前我们无法使用其他结构的字段。但是我该如何进行方法同步呢?

最佳答案

闭包需要对 self.map 的可变引用,以便向其中插入内容。但是闭包捕获只适用于整个绑定(bind)。这意味着,如果你说 self.map,闭包会 try catch self,而不是 self.map。并且 self 不能被可变地借用/捕获,因为部分 self 已经被不变地借用了。

我们可以通过单独为 map 引入一个新的绑定(bind)来解决这个闭包捕获问题,这样闭包就可以捕获它(Playground):

let mm = &mut self.map;
let mut lambda = |text: String| {
let _ = mm.insert("hello".to_owned(), text);
};
lambda("dd".to_owned());

但是,您忽略了一些事情:因为synchronized_call() 接受&mut self,所以您不需要互斥量!为什么? 可变引用 也称为独占引用,因为编译器可以在编译时确保在任何给定时间只有一个这样的可变引用。

因此,您静态地知道,在任何给定时间,最多有一个 synchronized_call() 实例在一个特定对象上运行,如果 该函数不是递归的(调用自身)。

如果您对互斥量具有可变访问权限,您就知道该互斥量已解锁。参见 the Mutex::get_mut() method for more explanation .是不是很神奇?

关于rust - 使用它的守卫时如何避免互斥量借用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41197088/

25 4 0