首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解一个终生问题

理解一个终生问题
EN

Stack Overflow用户
提问于 2020-04-04 20:11:44
回答 1查看 67关注 0票数 3

在编译我对Firecracker (在aarch64上,但我怀疑这个问题是否与架构相关)所做的更改时,我遇到了一个终生错误:

代码语言:javascript
复制
error[E0716]: temporary value dropped while borrowed
   --> src/vmm/src/device_manager/mmio.rs:174:24
    |
174 |           let int_evt = &serial
    |  ________________________^
175 | |             .lock()
176 | |             .expect("Poisoned legacy serial lock")
    | |__________________________________________________^ creates a temporary which is freed while still in use
177 |               .interrupt_evt();
    |                               - temporary value is freed at the end of this statement
178 |           vm.register_irqfd(int_evt, self.irq)
    |                             ------- borrow later used here
    |
    = note: consider using a `let` binding to create a longer lived value

原始代码(编译良好)是:

代码语言:javascript
复制
vm.register_irqfd(&serial
        .lock()
        .expect("Poisoned legacy serial lock")
        .interrupt_evt(), self.irq)
    .map_err(Error::RegisterIrqFd)?;

我不明白这有什么区别。错误消息似乎表明expect()正在返回临时值,并且我正在获取对它的常量引用,在C++中,这会延长临时值的生命周期,不是吗?无论哪种方式,为什么它在原始代码中可以工作,但在我绑定了一个l值之后就不行了(按照C++的说法,我不确定它是否也适用于Rust值)?

我尝试在这里创建一个SSCE,但它如预期的那样工作!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-04 20:53:25

问题的一个简单的、可重现的例子(playground):

代码语言:javascript
复制
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);

// get reference to item inside array
let item: &i32 = mutex.lock().unwrap().get(0).unwrap();

// use reference for something
println!("item = {:?}", item);

mutex.lock().unwrap()返回一个MutexGuard<'_, Option<i32>>,它借用互斥锁内部的数据。它还拥有对数据的锁定,该锁定在解除守卫时释放,这意味着其他任何人都不能同时借用数据。

当您在该防护上调用内部类型的方法时(如上面示例中的.get,或代码中的.interrupt_evt ),它将在防护的生命周期内借用,因为您只能在防护存在的情况下安全地访问数据。但是防护并不存储在任何变量中,因此它只对该语句临时存在,并在语句结束时立即删除。因此,您不能在语句之外获得对数据的引用。

要解决这个问题非常简单:首先将卫士存储在变量中,然后从变量中借用。这将确保保护的寿命比您从它获得的引用(playground)更长:

代码语言:javascript
复制
// create array inside mutex
let mutex = Mutex::new([ 0i32 ]);

// get reference to item inside array
let guard = mutex.lock().unwrap();
let item: &i32 = guard.get(0).unwrap();

// use reference for something
println!("item = {:?}", item);

// guard is now destroyed at end of scope
// and mutex lock is released here
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61027885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档