我正在尝试使用布尔标志来表示线程应该退出。但是,目前我的代码违反了借用检查器规则。我理解它为什么违反这些规则,但我不知道最合适的设计是什么以及如何解决问题。
fn long_running(exit_flag: &bool) {
loop {
std::thread::sleep(std::time::Duration::from_secs(10));
if *exit_flag {
break;
}
}
}
fn main() {
let mut exit_flag = false;
std::thread::scope(
|scope| {
let handle = scope.spawn(
|| {
long_running(&exit_flag); # (1)
}
);
exit_flag = true; # (2)
// terminate the consumer poll loop
handle.join().expect("failed to join thread");
}
);
}
问题涉及标有# (1)
和 的行# (2)
。
# (1)
:引用exit_flag
自# (2)
:在引用仍被借用时尝试改变底层变量
由于借用检查规则,这是不允许的。
- 解决该问题的一个方法可能是堆分配标志,并使用它在两个线程之间共享数据。
- 但是,使用的目的
std::thread::scope
是允许启动一个可以从父(主)线程的堆栈访问局部变量的线程。
顺便说一下,这个想法是从这个帖子里得到的
这不起作用,因为
exit_flag
会被线程的闭包借用,同时还会通过 进行变异exit_flag = true;
。换句话说,无法保证线程exit_flag
在变异时已停止观察(这实际上是 的重点exit_flag
)。您需要一个
AtomicBool
来执行此操作:请注意,我删除了
handle.join()
,因为它thread::scope
已经保证返回时所有线程都已连接。