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
相关产品推荐
相关产品推荐

