[英]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.