【问题标题】:Understanding a lifetime issue了解一生的问题
【发布时间】:2020-04-04 12:11:43
【问题描述】:

在编译我为 Firecracker 所做的更改时遇到了终身错误(在 aarch64 上,但我怀疑这个问题与架构有关):

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

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

vm.register_irqfd(&serial
        .lock()
        .expect("Poisoned legacy serial lock")
        .interrupt_evt(), self.irq)
    .map_err(Error::RegisterIrqFd)?;

我不明白其中的区别。错误消息似乎表明 expect() 正在返回一个临时文件,并且我正在对它进行 const 引用,在 C++ 中这将延长临时文件的生命周期,不是在 Rust 中吗?无论哪种方式,为什么它在原始代码中起作用,但在我绑定到左值之后却不起作用(C++ 用语,我不确定它是否与 Rust 相同)?

我尝试在这里创建一个SSCE,但它按预期工作!

【问题讨论】:

标签: rust lifetime


【解决方案1】:

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

// 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):

// 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 2011-06-07
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    相关资源
    最近更新 更多