Showed an example, that raceconditions are still possible even with mutex
parent
9e36ee2d01
commit
b67f32704e
|
|
@ -0,0 +1,58 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
// A shared bank account starting with $100
|
||||
let account_balance = Arc::new(Mutex::new(100));
|
||||
|
||||
// Thread A: Attempts to withdraw $80
|
||||
let balance_clone1 = Arc::clone(&account_balance);
|
||||
let handle1 = thread::spawn(move || {
|
||||
// 1. CHECK: Lock the account just to check the balance
|
||||
let current_balance = *balance_clone1.lock().unwrap();
|
||||
|
||||
if current_balance >= 80 {
|
||||
println!("Thread A: Balance is ${}. Approval granted!", current_balance);
|
||||
|
||||
// Simulate a tiny delay (e.g., network latency or CPU context switch)
|
||||
// This gives Thread B time to sneak in and check the balance
|
||||
thread::sleep(Duration::from_millis(5));
|
||||
|
||||
// 2. ACT: Lock again to deduct the money
|
||||
let mut balance_guard = balance_clone1.lock().unwrap();
|
||||
*balance_guard -= 80;
|
||||
println!("Thread A: Successfully withdrew $80.");
|
||||
} else {
|
||||
println!("Thread A: Declined. Insufficient funds.");
|
||||
}
|
||||
});
|
||||
|
||||
// Thread B: Simultaneously attempts to withdraw $80
|
||||
let balance_clone2 = Arc::clone(&account_balance);
|
||||
let handle2 = thread::spawn(move || {
|
||||
// 1. CHECK: Lock the account just to check the balance
|
||||
let current_balance = *balance_clone2.lock().unwrap();
|
||||
|
||||
if current_balance >= 80 {
|
||||
println!("Thread B: Balance is ${}. Approval granted!", current_balance);
|
||||
|
||||
// Simulate a tiny delay (e.g., network latency or CPU context switch)
|
||||
// This gives Thread B time to sneak in and check the balance
|
||||
thread::sleep(Duration::from_millis(5));
|
||||
|
||||
// 2. ACT: Lock again to deduct the money
|
||||
let mut balance_guard = balance_clone2.lock().unwrap();
|
||||
*balance_guard -= 80;
|
||||
println!("Thread B: Successfully withdrew $80.");
|
||||
} else {
|
||||
println!("Thread B: Declined. Insufficient funds.");
|
||||
}
|
||||
});
|
||||
|
||||
handle1.join().unwrap();
|
||||
handle2.join().unwrap();
|
||||
|
||||
// Final result
|
||||
println!("Final Bank Balance: ${}", *account_balance.lock().unwrap());
|
||||
}
|
||||
Loading…
Reference in New Issue