rust ReentrartMutexGuard borrow_mut被阻止

icnyk63a  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(89)

有人能解释一下为什么我的代码在ReentrantMutexGuard上执行borrow_mut()时会死机吗?这是我的代码

use std::sync::Mutex;
use std::cell::RefCell;

use parking_lot::ReentrantMutex;

#[derive(Default)]
struct InnerData {
    ia: i32,
    ib: i32,
}

#[derive(Default)]
struct OuterData {
    oa: i32,
    ob: ReentrantMutex<RefCell<InnerData>>,
}

impl OuterData {
    fn foo(&self) {
        println!("fn foo begin");
        let mut b_mg = self.ob.lock();
        let mut b_data = b_mg.borrow_mut();
        println!("after acquiring lock");
        if b_data.ia == 3 {
            b_data.ib = 5;
        }
        println!("fn foo end");
    }
}

fn main() {
    let mut outer_data: OuterData = Default::default();
    let mut b_mg = outer_data.ob.lock();
    let mut b_data = b_mg.borrow_mut();
    b_data.ia = 3;

    if b_data.ia == 3 {
        outer_data.foo();
    }
}
hpxqektj

hpxqektj1#

评论意见摘要如下:可重入互斥体将在父作用域持有锁时授予您不可变访问子作用域中的内部值,但RefCell将 * 不 * 允许在父作用域的RefMut仍然活着时对其值进行可变访问,以遵守Rust的引用保证。
幸运的是,您不需要删除锁保护,但是您需要删除RefMut,以便在调用可能想要访问它的嵌套函数之前释放它对数据的独占控制。在您的代码中:

fn main() {
    let mut outer_data: OuterData = Default::default();
    let mut b_mg = outer_data.ob.lock();
    let mut b_data = b_mg.borrow_mut();
    b_data.ia = 3;

    drop(b_data); // <----------------
    outer_data.foo();
}

或者一些变化。您可能希望更好地封装内部可变性(以便限制RefMut的活动时间),从而更好地避免此问题。

相关问题