Dum*_*les 5 multithreading rust
我正在尝试使用a Condvar来限制在任何给定时间处于活动状态的线程数.我很难找到如何使用的好例子Condvar.到目前为止,我有:
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let thread_count_arc = Arc::new((Mutex::new(0), Condvar::new()));
let mut i = 0;
while i < 100 {
let thread_count = thread_count_arc.clone();
thread::spawn(move || {
let &(ref num, ref cvar) = &*thread_count;
{
let mut start = num.lock().unwrap();
if *start >= 20 {
cvar.wait(start);
}
*start += 1;
}
println!("hello");
cvar.notify_one();
});
i += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
给出的编译器错误是:
error[E0382]: use of moved value: `start`
--> src/main.rs:16:18
|
14 | cvar.wait(start);
| ----- value moved here
15 | }
16 | *start += 1;
| ^^^^^ value used here after move
|
= note: move occurs because `start` has type `std::sync::MutexGuard<'_, i32>`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
我完全不确定我的使用Condvar是否正确.我尝试尽可能接近Rust API上的示例.Wwat是实现这个的正确方法吗?
这是一个可以编译的版本:
use std::{
sync::{Arc, Condvar, Mutex},
thread,
};
fn main() {
let thread_count_arc = Arc::new((Mutex::new(0u8), Condvar::new()));
let mut i = 0;
while i < 100 {
let thread_count = thread_count_arc.clone();
thread::spawn(move || {
let (num, cvar) = &*thread_count;
let mut start = cvar
.wait_while(num.lock().unwrap(), |start| *start >= 20)
.unwrap();
// Before Rust 1.42, use this:
//
// let mut start = num.lock().unwrap();
// while *start >= 20 {
// start = cvar.wait(start).unwrap()
// }
*start += 1;
println!("hello");
cvar.notify_one();
});
i += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
Condvar::wait_while重要的部分可以从or的签名看出Condvar::wait:
pub fn wait_while<'a, T, F>(
&self,
guard: MutexGuard<'a, T>,
condition: F
) -> LockResult<MutexGuard<'a, T>>
where
F: FnMut(&mut T) -> bool,
Run Code Online (Sandbox Code Playgroud)
pub fn wait<'a, T>(
&self,
guard: MutexGuard<'a, T>
) -> LockResult<MutexGuard<'a, T>>
Run Code Online (Sandbox Code Playgroud)
这表示wait_while/wait 消耗了guard,这就是为什么你会得到你所做的错误 - 你不再拥有start,所以你不能调用它的任何方法!
这些函数很好地反映了 s 的工作原理- 您暂时放弃了( 由 表示)Condvar上的锁定,当函数返回时,您再次获得锁定。Mutexstart
解决方法是放弃锁,然后从wait_while/获取锁防护返回值wait。在 huon 的鼓励下,我也从 an 切换if到 a 。while