在 rust 的 `self` 方法中启动的线程中调用 `self` 的另一个方法

问题描述 投票:0回答:1

得到了这个相对简单的代码

use std::thread;


struct Runner {
    data: String
}

impl Runner {
    fn new(s: &str) -> Self {
        Self { data: s.to_owned() }
    }

    fn doit(&mut self) {
        // modify `self.data`
    }

    fn run(&mut self) {

        for _ in 0..4 {
            thread::spawn(move ||{
               self.doit(); 
            });
        }
    }
}

fn main() {
    let mut r = Runner::new("hello");
    r.run();
}

并且它无法编译,因为我正在移动

self
并且我完全理解为什么。 但我该怎么做才能实现想要的行为?

我希望能够从正在运行的线程更改

data
。所以我实际上需要
Mutex
来完成整个
self
事情。

如何实现这一目标?还有另一种惯用的方法吗?

rust struct thread-safety borrow-checker
1个回答
0
投票

尝试使用 std::sync::Arc(线程安全引用计数指针)和 Mutex 来保护共享数据:

use std::sync::{Arc, Mutex};
use std::thread;

#[derive(Debug)]
struct Runner {
    data: String,
}

impl Runner {
    fn new(s: &str) -> Self {
        Self { data: s.to_owned() }
    }

    fn doit(&mut self) {
        // modify `self.data`
        self.data.push_str(".w");
    }

    fn run(r: Arc<Mutex<Runner>>) {
        let mut handles = vec![];
        for _ in 0..4 {
            let rc = Arc::clone(&r);

            let h = thread::spawn(move || {
                rc.lock().unwrap().doit();
                dbg!(rc);
            });

            handles.push(h);
        }

        for h in handles {
            h.join().unwrap();
        }
    }
}

fn main() {
    let r = Arc::new(Mutex::new(Runner::new("hello")));
    Runner::run(r);
}
© www.soinside.com 2019 - 2024. All rights reserved.