我正在Rust中试验多线程。我已经创建了一个基于Eratosthenes筛子的玩具示例来寻找素数。每个工作线程都有一个素数列表,作为新候选者的因子进行检查。
for chunk in &primes {
let tx2 = mpsc::Sender::clone(&tx);
let p2 = Arc::clone(chunk);
thread::spawn(move || {
let result = divisible_by_any(i, &p2.lock().unwrap());
tx2.send(result).unwrap();
});
}
let mut any = false;
for _i in 0..primes.len() {
let result = rx.recv().unwrap();
if result { any = true }
}一种可能的优化是,只要任何线程找到除数,就允许环引导器进程“中断”工作线程。我想象工作线程(divisible_by_any)不会被杀死,但会检查某种类型的信号量,以指示“中断”是否已被请求,以便它可以停止扫描除数。
用来引发可被多个CPU绑定的工作线程注意/采样的信号量的Rust惯用法是什么?
发布于 2021-01-01 02:29:35
Rust中的文字中断通常不会完成,因为中断的副作用可能会干扰涉及借用和删除的语言保证。这里的最佳实践是,如果您不能简单地让工作线程将精力浪费在其剩余的块上,那么工作线程定期轮询某种简单的状态对象。
let quit_flag = Arc::new(AtomicBool::new(false));
for chunk in &primes {
let tx2 = mpsc::Sender::clone(&tx);
let p2 = Arc::clone(chunk);
let qf = Arc::clone(quit_flag);
thread::spawn(move || {
// repeatedly accessing an &AtomicBool is cheaper than an
// Arc<AtomicBool>, so we're unwrapping it here.
let quit = qf.as_ref();
// divisible_by_any needs to check the quit flag occasionally.
let result = divisible_by_any(i, &p2.lock().unwrap(), quit);
tx2.send(result).unwrap();
});
}
for _i in 0..primes.len() {
let result = rx.recv().unwrap();
if result.is_some() { (*quit_flag).store(true, Ordering::Relaxed); }
}
// Some parts of this are best-guesses and pseudocode
fn divisible_by_any(i: Integer, chunk: Chunk, quit: &AtomicBool) -> Option<Integer>
{
for sub_chunk in chunk.sub_chunks() {
if quit.load(Ordering::Relaxed) {
return None;
}
for j in sub_chunk {
// do work, maybe returning Some(Integer)
}
}
None
}https://stackoverflow.com/questions/65523128
复制相似问题