【问题标题】:How to use mutexes in threads without Arc? [closed]如何在没有 Arc 的线程中使用互斥锁? [关闭]
【发布时间】: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 被删除后(函数返回时)不会在线程中使用&amp;found_primes,即使我.join() 所有线程在那之前。我猜我需要不安全的代码才能使其工作。不过,我不明白第二个错误。

有人可以解释错误并告诉我如何仅使用Mutexes 执行此操作吗?

【问题讨论】:

标签: multithreading rust mutex


【解决方案1】:

最后一个错误是抱怨试图将内容移出互斥体。 .lock() 返回一个 MutexGuard,它只产生对内容的引用。你不能离开它,否则它会使互斥锁处于无效状态。您可以通过克隆来获得拥有的值,但如果互斥体无论如何都将消失,那就没有必要了。

您可以使用.into_inner()使用互斥体并返回其中的内容。

found_primes.into_inner().expect("Mutex was poisoned!")

playground 上查看此修复和其他链接修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多