如何共享指向线程的可变变量的指针?

时间:2019-04-19 08:25:56

标签: rust thread-safety uci

我必须为我的国际象棋引擎实现UCI protocol

它需要从命令行读取命令。发送go命令后,必须开始搜索。但是,在此搜索过程中,仍必须接收其他命令,例如stop。对于stop,必须完全退出搜索。

这是代码的外观(省略了不重要的细节)。

pub fn main() {
    let mut stop: bool = false;
    loop {
        line.clear();
        stdin.read_line(&mut line).ok().unwrap();
        let arg: Vec<&str> = line.split_whitespace().collect();
        let cmd = arg[0];
        match cmd.trim() {
            "" => continue,
            "go" => {
                stop = false;
                thread::spawn(move || start_search(&stop, GameState, History, Timecontrol));
            }
            "stop" => {
                stop = true;
                thread::sleep(Duration::from_millis(50));
            }
            "quit" => {
                stop = true;
                thread::sleep(Duration::from_millis(50));
                break;
            }
            _ => {
                println!("Unknown command {}", line);
            }
        }
    }
}

pub fn start_search(stop_reference: &bool, _: GameState, _: History, _: Timecontrol) {
    /* Do search stuff here...
     */
    //Has to break when stop_reference is set to true
}

此代码无法正常工作,因为我认为只是复制了该字段。但是我尝试给出结构,然后代码抱怨,因为您不能同时具有可变引用和普通引用。我还研究了与线程通信的方法。但是,大多数解决方案都使用通道来实现这一点,但是我认为通道在我的情况下不起作用,因为线程始终在计算,因此无论如何终止它只会接收通道的命令。

1 个答案:

答案 0 :(得分:3)

您需要使用特殊的引用Arc来在线程之间共享布尔值:

pub fn main() {
    let stop = Arc::new(AtomicBool::new(false));
    loop {
        //...

        let stop = Arc::clone(&stop);
        thread::spawn(move || {
            start_search(stop);
        })
    }
}
pub fn start_search(stop: Arc<AtomicBool>) {
    loop {
        if stop.load(Ordering::Relaxed) {
            // STOP
        }
    }
}