How do I share access to an AtomicBool between threads?
There are two ways to access variables between threads:
- borrowing, which requires guaranteeing that the variable's lifetime exceeds the threads' lifetime
- shared ownership (via
Arc
):
Borrowing is not supported by the Standard Library at the moment, although 3rd-party crates such as crossbeam offer it. For shared ownership, Arc
is indeed a possibility...
... however you need to consider what you put in Arc
carefully:
let stop_bool = Arc::new(&self.should_stop).clone();
Here, you are creating a Arc<&'a AtomicBool>
from a &'a self
, and thus you are sharing ownership over a borrowed reference. I'll point you back to the above explanation: cross-thread borrowing is not supported in the Standard Library yet.
You need a Arc<AtomicBool>
for proper shared ownership, and this is done by changing Test
:
struct Test { should_stop: Arc<AtomicBool>, running_thread_handles: Vec<JoinHandle<()>>}
Then, cloning it is easy:
let stop_bool = self.should_stop.clone();
I'm posting my own answer here to hopefully provide a clear generic example, since the accepted answer is quite specific to the original question and left me slightly unsure how to do it:
use std::{thread, time};use std::sync::atomic::{AtomicBool, Ordering};use std::sync::Arc;fn main() { let stop = Arc::new(AtomicBool::new(false)); let stop_me = stop.clone(); thread::spawn(move || { let mut i = 0; loop { i = i + 1; if stop_me.load(Ordering::Relaxed) { println!("iterations = {}", i); break; } if i % 1000000 == 0 { println!("Another million iterations down..."); } } }); let delay = time::Duration::from_millis(100); thread::sleep(delay); stop.store(true, Ordering::Relaxed); println!("All done");}
Rust playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4a36363b361b5b933d9e70989a18d67a