如何在不移动 Mutex 变量的情况下使用 Condvar?
How do I use a Condvar without moving the Mutex 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。我发现的两个区别是:
- 他们创造了一对
Condvar
和 Mutex
。这应该无关紧要,对吧?我想单独创建它们。
- 它们使用
ref
关键字匹配锁,如果我理解 this 正确回答,这意味着对锁的引用。我认为通过将行更改为 cvar.wait(&unlocked).unwrap();
将是同一件事,但随后编译器抱怨预期是 MutexGuard
而不是引用。
如何让它编译?
您没有发现的区别在于wait
returns 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();
}
另请参阅:
我想在我的程序中使用 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
而不是引用。
如何让它编译?
您没有发现的区别在于wait
returns 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();
}
另请参阅: