简体   繁体   English

Rust:使用Mutex和Arc进行变异

[英]Rust: Using Mutex and Arc to mutate

I am trying to allow multiple threads to mutate the same variable using Arc and a Mutex lock, but it seems as though I am unable to get ownership of the variable, even after cloning it?我试图允许多个线程使用 Arc 和互斥锁来改变同一个变量,但似乎我无法获得该变量的所有权,即使在克隆它之后也是如此?

// modifed example from https://doc.rust-lang.org/beta/rust-by-example/std/arc.html
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

fn main() {
    // This variable declaration is where its value is specified.
    let test = Arc::new(Mutex::new(TestStruct{
        counter: 0,
    }));
    
    println!("Initial Counter Value: 0");

    for _ in 0..10 {
        // Here there is no value specification as it is a pointer to a
        // reference in the memory heap.
        let test = Arc::clone(&test);

        thread::spawn(move || {
            // As Arc was used, threads can be spawned using the value allocated
            // in the Arc variable pointer's location.
            test.lock().unwrap().increment();
        });
    }

    // Make sure all Arc instances are printed from spawned threads.
    thread::sleep(Duration::from_secs(1));
    println!("Final Counter Value: {:?}", test.lock().unwrap().counter);
}

#[derive(Debug)]
struct TestStruct {
    // counter
    counter: i32,
}

impl TestStruct {
    // increment counter
    fn increment(mut self) {
        self.counter +=1;
    }
}

I keep getting errors that say error[E0507]: cannot move out of dereference of "MutexGuard<"_, TestStruct> anywhere that I try to access the variable with test.lock().unwrap()我不断收到错误error[E0507]: cannot move out of dereference of "MutexGuard<"_, TestStruct>在我尝试使用test.lock().unwrap()访问变量的任何地方

All I am trying to do in this example is increment a counter from multiple threads, and then check the value of this counter afterwards.在这个例子中我想做的就是从多个线程递增一个计数器,然后检查这个计数器的值。 I've gotten it to work by placing the value inside of an option: Arc::new(Mutex::new(Some(TestStruct{..}))) and then taking the value from that option: test.lock().unwrap().take() , but taking the value out of the Option then replaces it with None, so it only works once.我通过将值放在一个选项中来让它工作: Arc::new(Mutex::new(Some(TestStruct{..})))然后从该选项中获取值: test.lock().unwrap().take() ,但是从 Option 中取出值然后用 None 替换它,所以它只工作一次。

Does anyone know what I am doing wrong / how I might be able to get this to work?有谁知道我做错了什么/我怎样才能让它发挥作用?

Here is a link to a playground with the code. 这是带有代码的游乐场的链接。

Since you take mut self as opposed to &mut self in increment you need to exclusively own the variable to use it.由于您采用mut self而不是&mut self增量,因此您需要独占该变量才能使用它。 But you can only take references to objects in Arc<Mutex<…>> .但是您只能引用Arc<Mutex<…>>中的对象。 You probably want to take self by mutable reference in increment instead:您可能希望通过可变引用以increment方式获取self

impl TestStruct {
    // increment counter
    fn increment(&mut self) {
        self.counter +=1;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM