如何在不移动Mutex变量的情况下使用Condvar?

时间:2019-07-08 16:52:40

标签: rust condition-variable

我想在程序中使用Condvar。下面是对它的简短测试。我知道它将永远卡在循环中。

use std::sync::{Arc, Condvar, Mutex};

fn main() {
    let var_in_lock = Arc::new(Mutex::new(8));
    let cvar = Arc::new(Condvar::new());

    let unlocked = var_in_lock.lock().unwrap();

    loop {
        cvar.wait(unlocked).unwrap();
    }
}

无法编译:

error[E0382]: use of moved value: `unlocked`
  --> src/main.rs:10:19
   |
7  |     let unlocked = var_in_lock.lock().unwrap();
   |         -------- move occurs because `unlocked` has type `std::sync::MutexGuard<'_, i32>`, which does not implement the `Copy` trait
...
10 |         cvar.wait(unlocked).unwrap();
   |                   ^^^^^^^^ value moved here, in previous iteration of loop

我已经查看了Rust文档中的the example。我发现的两个区别是:

  1. 他们成对创建CondvarMutex。没关系吧?我想分别创建它们。
  2. 它们使用ref关键字来匹配锁,如果我正确理解this的答案,则表示对锁进行了引用。我发现通过将行更改为cvar.wait(&unlocked).unwrap();是同一回事,但是随后编译器抱怨期望使用MutexGuard而不是引用。

我如何进行编译?

1 个答案:

答案 0 :(得分:1)

没有发现的区别是wait返回了MutexGuard

pub fn wait<'a, T>(
    &self,
    guard: MutexGuard<'a, T>
) -> LockResult<MutexGuard<'a, T>>
while !*started {
    started = cvar.wait(started).unwrap();
}

wait拥有MutexGuard的所有权,因为它释放了锁,后来又重新获得了它。静态转移所有权可以防止使用不正确的锁定(或解锁)变量,这是使用Rust的类型系统为程序员带来好处的示例。


您需要在代码中执行相同的操作:

let mut unlocked = var_in_lock.lock().unwrap();

loop {
    unlocked = cvar.wait(unlocked).unwrap();
}

另请参阅: