Skip to content

Instantly share code, notes, and snippets.

@lostkagamine
Created February 8, 2022 20:38
Show Gist options
  • Save lostkagamine/25e2073769d16e11c87dfc918e15ded5 to your computer and use it in GitHub Desktop.
Save lostkagamine/25e2073769d16e11c87dfc918e15ded5 to your computer and use it in GitHub Desktop.
An example of how concurrency can fail gracefully in Rust
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