本文介绍了从Mutex一起借用参考资料和防护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试封装一些代码,以避免重复代码,这涉及从Mutex中借用数据并对其进行进一步的操作(我将这个问题排除在范围之外,但这是激励因素).

I'm trying to encapsulate some code to avoid repeating it, relating to borrowing data out of a Mutex and further operations thereupon (which I leave off of this question as out of scope, but are the motivating factors).

以下示例代码抱怨guard的寿命不足.但这就是为什么我要在专门为此目的设计的结构中返回guard的原因.

The following sample code complains that guard does not live long enough. But that is precisely why I'm returning guard in the structure designed expressly for that purpose.

这是借阅检查器的限制吗?有任何解决此问题的建议吗?

Is this a limitation of the borrow checker? Any suggestions on working around this?

use std::sync::{Mutex,MutexGuard};
use std::ops::DerefMut;

pub struct InnerData {
    count: i32  // sample only
}

pub struct Data {
    pub inner_data: Mutex<InnerData>
}

pub struct BorrowedInnerData<'a> {
    pub inner_data: &'a mut InnerData,
    guard: MutexGuard<'a,InnerData>,
}

impl Data {
    pub fn borrow_inner_data<'a>(&'a mut self) -> BorrowedInnerData<'a> {
        let guard = self.inner_data.lock().unwrap();
        BorrowedInnerData {
            inner_data: guard.deref_mut(),
            guard: guard,
        }
    }
}

fn main() {
    let mut data = Data {
        inner_data: Mutex::new( InnerData {
            count: 5
        }),
    };

    let borrowed_inner_data = data.borrow_inner_data();
}

推荐答案

让我们看一下 DerefMut特征:

Let's look at the DerefMut trait:

pub trait DerefMut: Deref {
    fn deref_mut(&'a mut self) -> &'a mut Self::Target;
}

这意味着在调用deref_mut时,将返回一个引用,该引用只要被取消引用的值就有效.但是,将guard移到BorrowedInnerData时,您正在移动.这意味着该值停止驻留在一个存储位置,而开始于新的存储位置.正如 Veedrac提示,完全有可能移动警卫,您将使参考无效.这将很糟糕,并导致崩溃(在最佳情况下).

This means that when deref_mut is called, a reference is returned that lives as long as the value being dereferenced. However, you are moving guard when you move it to BorrowedInnerData. This means that the value stops living at one memory location and starts at a new one. As Veedrac hints at, it's entirely possible that by moving the guard, you would invalidate the reference. This would be bad and lead to crashes (in the best case).

但是,没有真正的理由保留guardinner_data.由于DerefDerefMut,可以像&InnerData&mut InnerData一样使用MutexGuard<InnerData>.只需从结构中删除inner_data并保留guard.

However, there's no real reason to keep guard and inner_data. Because of Deref and DerefMut, a MutexGuard<InnerData> can be used just like a &InnerData or &mut InnerData. Simply remove inner_data from your struct and keep guard.

这篇关于从Mutex一起借用参考资料和防护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-09 22:37