You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust国际象棋引擎线程未执行内部代码问题求助

Rust国际象棋引擎线程未执行内部代码问题求助

我正在用Rust写一个国际象棋引擎,想让它启动一个线程,这样它思考的时候还能监听UCI命令。我先写了个简化版的测试代码,完全符合预期——能通过stop flag通知主线程停止AI线程并成功join。

测试代码如下:

#[test]
fn start_thread() {
    let test_struct = TestStruct { stop_flag: None, test_data: String::from("not modified") };
    println!("{}", test_struct.test_data);
    let x = test_struct.start_thread();
    thread::sleep(Duration::from_secs(1));
    let test_struct = x.stop();
    println!("{}", test_struct.test_data);
}

pub struct ThreadInfo {
    stop_flag: Arc<AtomicBool>,
    join_handle: JoinHandle<TestStruct>,
}

impl ThreadInfo {
    pub fn stop(self) -> TestStruct {
        println!("stopping");
        self.stop_flag.store(true, Ordering::SeqCst);
        println!("stop flag main thread: {}", self.stop_flag.load(Ordering::Relaxed));
        let mut ai = self.join_handle.join().expect("failed to join thread");
        ai.stop_flag = None;
        println!("stopped");
        ai
    }
}

struct TestStruct {
    stop_flag: Option<Arc<AtomicBool>>,
    test_data: String,
}

impl TestStruct {
    pub fn start_thread(mut self) -> ThreadInfo {
        let stop_flag = Arc::new(AtomicBool::new(false));
        let stop_flag_clone = Arc::clone(&stop_flag);
        self.stop_flag = Some(stop_flag_clone);

        println!("starting");

        let handle = thread::spawn(move || {
            println!("thread start");
            loop {
                println!("thread running");
                //let start_time = Instant::now();
                //let evaluation = self.negamax(&self.game.deep_clone(), depth, 0, -INFINITY, INFINITY);
                //let pv_string = self.reconstruct_principal_variation();
                if let Some(stop_flag) = &self.stop_flag {
                    if stop_flag.load(Ordering::Relaxed) { break; }
                }
                self.test_data = String::from("modified");
                //let depth_duration = start_time.elapsed();
                //Self::uci_print_evaluation_info(evaluation, depth, depth_duration, pv_string);
                //self.uninterupted_best_move = Some(self.last_principal_variation[0]);
            }
            self
        });

        println!("started {:?}", handle);

        ThreadInfo {
            stop_flag: stop_flag,
            join_handle: handle,
        }
    }
}

但到了实际引擎代码里就完全不行了——我在线程的第一行加了panic!语句,结果根本没触发panic,说明线程内部的代码根本没跑。而且stop flag也没法停止线程,join也永远完成不了。我实在看不出实际代码和测试代码有啥区别,以下是引擎里的相关代码:

pub struct ThreadInfo {
    stop_flag: Arc<AtomicBool>,
    join_handle: JoinHandle<AI>,
}

impl ThreadInfo {
    pub fn stop(self) -> AI {
        println!("stopping");
        self.stop_flag.store(true, Ordering::SeqCst);
        println!("stop flag main thread: {}", self.stop_flag.load(Ordering::Relaxed));
        let mut ai = self.join_handle.join().expect("failed to join thread");
        ai.stop_flag = None;
        println!("stopped");
        ai
    }
}


pub struct AI {
    move_data: AllMoveData,
    hashes: Hashes,
    game: Game,
    name: String,
    transposition_table: TranspositionTable,
    last_principal_variation: Vec<EncodedMove>,
    stop_flag: Option<Arc<AtomicBool>>,
    uninterupted_best_move: Option<EncodedMove>,
}
impl AI {
    pub fn start_thread(mut self) -> ThreadInfo {
        let stop_flag = Arc::new(AtomicBool::new(false));
        let stop_flag_clone = Arc::clone(&stop_flag);
        self.stop_flag = Some(stop_flag_clone);

        println!("starting");

        let handle = thread::spawn(move || {
            println!("thread start");
            panic!("thread started! yay!");
            for depth in 1..MAX_DEPTH {
                let start_time = Instant::now();
                let evaluation = self.negamax(&self.game.deep_clone(), depth, 0, -INFINITY, INFINITY);
                let pv_string = self.reconstruct_principal_variation();
                if self.check_stop_flag() { break; }
                let depth_duration = start_time.elapsed();
                Self::uci_print_evaluation_info(evaluation, depth, depth_duration, pv_string);
                self.uninterupted_best_move = Some(self.last_principal_variation[0]);
            }
            self
        });

        println!("started {:?}", handle);

        ThreadInfo {
            stop_flag: stop_flag,
            join_handle: handle,
        }
    }

    fn check_stop_flag(&self) -> bool {
        if let Some(stop_flag) = &self.stop_flag {
            return stop_flag.load(Ordering::Relaxed);
        }
        false
    }
}

main.rs里调用这段代码的部分是:

let ai_thread = ai.start_thread();
thread::sleep(Duration::from_millis(move_time));
ai = ai_thread.stop();
writeln!(handle, "bestmove {}", ai.get_best_move()).unwrap();

我的negamax和quiescence函数开头和循环里都会调用check_stop_flag,一旦检测到就返回0,用上一次完成的搜索结果。当我设置1000毫秒运行时,程序确实会在打印"starting"和"stopping"之间等一秒,但永远到不了"stopped",也不会输出最佳走法。看起来线程内部的代码根本没执行,这到底是为啥啊?

备注:内容来源于stack exchange,提问作者UnoriginalName369636

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 02:54:44