I need to have a global boolean flag that will be accessed by multiple threads.
Here is an example of what I need:
static GLOBAL_FLAG: SyncLazy<Mutex<bool>> = SyncLazy::new(|| {
Mutex::new(false)
});
fn set_flag_to_true() { // can be called by 2+ threads concurrently
*GLOBAL_FLAG.lock().unwrap() = true;
}
fn get_flag_and_set_to_true() -> bool { // only one thread is calling this function
let v = *GLOBAL_FLAG.lock().unwrap(); // Obtain current flag value
*GLOBAL_FLAG.lock().unwrap() = true; // Always set the flag to true
v // Return the previous value
}
The get_flag_and_set_to_true()
implementation doesn't feel quite right. I imagine it would be best if I only locked once. What's the best way to do that?
BTW I suppose Arc<[AtomicBool]>
can also be used and should in theory be faster, although in my particular case the speed benefit will be unnoticeable.
BTW I suppose
Arc<[AtomicBool]>
can also be used and should in theory be faster, although in my particular case the speed benefit will be unnoticeable.
It's not just about benefit in performance, but also in amount of code and ease of reasoning about the code. With AtomicBool
you don't need either SyncLazy
or the mutex, and the code is shorter and clearer:
use std::sync::atomic::{AtomicBool, Ordering};
static GLOBAL_FLAG: AtomicBool = AtomicBool::new(false);
pub fn set_flag_to_true() {
GLOBAL_FLAG.store(true, Ordering::SeqCst);
}
pub fn get_flag_and_set_to_true() -> bool {
GLOBAL_FLAG.swap(true, Ordering::SeqCst)
}
Playground
Conceivably, another thread could come in between when you read GLOBAL_FLAG
and when you set GLOBAL_FLAG
to true. To work around this you can directly store the MutexGuard
(docs) that GLOBAL_FLAG.lock().unwrap()
returns:
fn get_flag_and_set_to_true() -> bool { // only one thread is calling this function
let mut global_flag = GLOBAL_FLAG.lock().unwrap();
let v = *global_flag; // Obtain current flag value
*global_flag = true; // Always set the flag to true
v // Return the previous value
}
global_flag
will keep the mutex locked until it gets dropped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With