我想在程序中使用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。我发现的两个区别是:
Condvar
和Mutex
。没关系吧?我想分别创建它们。ref
关键字来匹配锁,如果我正确理解this的答案,则表示对锁进行了引用。我发现通过将行更改为cvar.wait(&unlocked).unwrap();
是同一回事,但是随后编译器抱怨期望使用MutexGuard
而不是引用。我如何进行编译?
答案 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();
}
另请参阅: