【发布时间】:2020-10-31 18:51:06
【问题描述】:
我有一个函数应该在给定范围内搜索素数。 (算法并不重要,请忽略它非常低效的事实。)
use std::thread;
use std::sync::Mutex;
use std::convert::TryInto;
/// Takes the search range as (start, end) and outputs a vector with the primes found within
/// that range.
pub fn run(range: (u32, u32)) -> Vec<u32> {
let mut found_primes: Mutex<Vec<u32>> = Mutex::new(Vec::new());
let num_threads: usize = 8;
let num_threads_32: u32 = 8;
let join_handles: Vec<thread::JoinHandle<()>> = Vec::with_capacity(num_threads);
// ERROR: `found_primes` does not live long enough
let vec_ref = &found_primes;
for t in 0..num_threads_32 {
thread::spawn(move || {
let mut n = range.0 + t;
'n_loop: while n < range.1 {
for divisor in 2..n {
if n % divisor == 0 {
n += num_threads_32;
continue 'n_loop;
}
}
// This is the part where I try to add a number to the vector
vec_ref.lock().expect("Mutex was poisoned!").push(n);
n += num_threads_32;
}
println!("Thread {} is done.", t);
});
}
for handle in join_handles {
handle.join();
}
// ERROR: cannot move out of dereference of `std::sync::MutexGuard<'_, std::vec::Vec<u32>>`
*found_primes.lock().expect("Mutex was poisoned!")
}
我设法让它与std::sync::mpsc 一起工作,但我很确定它可以只用互斥锁来完成。但是,借阅检查器不喜欢它。
错误在 cmets 中。我(想我)理解第一个错误:编译器无法证明found_primes 被删除后(函数返回时)不会在线程中使用&found_primes,即使我.join() 所有线程在那之前。我猜我需要不安全的代码才能使其工作。不过,我不明白第二个错误。
有人可以解释错误并告诉我如何仅使用Mutexes 执行此操作吗?
【问题讨论】:
-
请删除所有不相关的代码并添加您遇到的错误。
-
@user2722968 大部分代码都是相关的,错误在 cmets 中。我编辑了我的问题;请阅读。
-
您的第一个错误在这里得到解答:Parameter type may not live long enough (with threads)
-
第一个错误由How can I pass a reference to a stack variable to a thread? 解决(或链接kmdreko 发布,也链接到那里)。第二个在别处没解决,不过是completely unrelated to the first one。我投票结束这篇文章,因为它没有重点,因为到目前为止,这个独特的问题被隐藏在所有主题内容(在其他地方已经得到充分回答)之下,我怀疑它对未来的读者是否有用。
标签: multithreading rust mutex