Created
February 8, 2022 20:38
-
-
Save snightshade/25e2073769d16e11c87dfc918e15ded5 to your computer and use it in GitHub Desktop.
An example of how concurrency can fail gracefully in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::sync::{Arc, Mutex, PoisonError}; | |
use std::thread; | |
fn main() { | |
let the_lock = Arc::new(Mutex::<i32>::new(0)); | |
{ | |
let lock = the_lock.clone(); | |
thread::spawn(move || { | |
let mut value = lock.lock().expect("failed to acquire lock on thread 1"); | |
for _ in 0..100 { | |
*value += 1; | |
} | |
// 'value' has not fallen out of scope! | |
// the mutex is locked, therefore it is now poisoned | |
// because this thread will now panic. | |
panic!("very naughty"); | |
}); | |
} | |
{ | |
let lock = the_lock.clone(); | |
thread::spawn(move || { | |
// Just ignore the PoisonError here - we'll check later. | |
let mut value = match lock.lock() { | |
Ok(x) => x, | |
Err(x @ PoisonError { .. }) => x.into_inner() | |
}; | |
for _ in 0..1000 { | |
*value += 1; | |
} | |
}).join().ok(); // wait for the thread to end. discard the failure if any happens | |
} | |
println!("The number is: {}", match the_lock.lock() { | |
Ok(x) => format!("{}", x), // we're fine | |
Err(x @ PoisonError { .. }) => format!("{1} (MUTEX WAS POISONED: {0})", x.to_string(), x.into_inner()) | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment