- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个小程序 - 本质上我希望一个线程能够通过结构中的共享 bool 值告诉另一个线程停止。
use std::thread;
use std::thread::JoinHandle;
use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
struct Test {
should_stop: AtomicBool,
running_thread_handles: Vec<JoinHandle<()>>
}
impl Test {
fn new() -> Test {
Test {
should_stop: AtomicBool::new(false),
running_thread_handles: Vec::new()
}
}
fn stop(&mut self) {
self.should_stop.store(true, Ordering::Relaxed);
}
fn start(&mut self) {
let handle = thread::spawn(move || {
loop {
println!("Looping");
thread::sleep(Duration::from_millis(500));
// I want to effectively do this...
/*
if self.stop_bool.load(Ordering::Relaxed) {
println!("Stopping");
break;
}*/
}
});
self.running_thread_handles.push(handle);
}
}
impl Drop for Test {
fn drop(&mut self) {
self.stop();
// Here I want to iterate the self.running_thread_handles and
// make sure they are cleaned up
}
}
// I expect to see a 4 "Looping" messages and then a "Stopping" message
fn main() {
let mut test = Test::new();
test.start();
thread::sleep(Duration::from_millis(2000));
test.stop();
}
也许有更好的方法,但我认为这可能是稍微了解生命周期的好方法。
我认为我只需要一个 Arc
所以我尝试了这个:
fn start(&mut self) {
let stop_bool = Arc::new(&self.should_stop).clone();
let handle = thread::spawn(move || {
loop {
println!("Looping");
thread::sleep(Duration::from_millis(500));
if stop_bool.load(Ordering::Relaxed) {
println!("Stopping");
break;
}
}
});
self.running_thread_handles.push(handle);
}
这给了我这个错误:
error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
我认为编译器不理解线程的生命周期,因为我所做的只是将句柄存储在向量中,所以我需要以某种方式告诉它,但如何呢?
如果我像这样声明结构体,我会更接近于让它发挥作用吗?
struct Test<'a> {
should_stop: AtomicBool,
running_thread_handles: &'a Vec<JoinHandle<()>>
}
我还有一些次要的、相关的麻烦,我终生无法弄清楚如何遍历我的句柄向量并在 Drop
impl 中调用它们的任何函数。我想这个问题的解决方案是相关的,所以我不会问这个问题。
最佳答案
线程间访问变量有两种方式:
Arc
):目前标准库不支持借用,尽管第 3 方 crate 如 crossbeam提供它。对于共享所有权,Arc
确实有可能……
...但是您需要考虑您在 Arc
中输入的内容小心:
let stop_bool = Arc::new(&self.should_stop).clone();
在这里,您正在创建一个 Arc<&'a AtomicBool>
来自&'a self
,因此您共享对借用引用的所有权。我会让你回到上面的解释:标准库还不支持跨线程借用。
你需要一个Arc<AtomicBool>
为了适当的共享所有权,这是通过更改 Test
来完成的:
struct Test {
should_stop: Arc<AtomicBool>,
running_thread_handles: Vec<JoinHandle<()>>
}
然后,克隆它很容易:
let stop_bool = self.should_stop.clone();
关于multithreading - 如何在线程之间共享对 AtomicBool 的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33911792/
我有这个小程序 - 本质上我希望一个线程能够通过结构中的共享 bool 值告诉另一个线程停止。 use std::thread; use std::thread::JoinHandle; use st
我是一名优秀的程序员,十分优秀!