Showing an example, that deadlocks are still possible

main
3008505 2026-06-13 13:03:57 +00:00
parent b67f32704e
commit 65b4d44f7a
1 changed files with 47 additions and 0 deletions

View File

@ -0,0 +1,47 @@
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
// 1. Create two separate resources, each protected by its own Mutex
let resource_a = Arc::new(Mutex::new("Resource A Data"));
let resource_b = Arc::new(Mutex::new("Resource B Data"));
// 2. Thread 1: Tries to lock A first, then B
let a_clone1 = Arc::clone(&resource_a);
let b_clone1 = Arc::clone(&resource_b);
let handle1 = thread::spawn(move || {
// Grab Lock A
let _guard_a = a_clone1.lock().unwrap();
println!("Thread 1: Successfully locked Resource A!");
// Sleep for a moment to guarantee Thread 2 has time to lock Resource B
thread::sleep(Duration::from_millis(10));
println!("Thread 1: Trying to lock Resource B... (Waiting)");
let _guard_b = b_clone1.lock().unwrap(); // Stalled forever here
println!("Thread 1: Successfully locked Resource B!");
});
// 3. Thread 2: Tries to lock B first, then A (The opposing order causes the deadlock!)
let a_clone2 = Arc::clone(&resource_a);
let b_clone2 = Arc::clone(&resource_b);
let handle2 = thread::spawn(move || {
// Grab Lock B
let _guard_b = b_clone2.lock().unwrap();
println!("Thread 2: Successfully locked Resource B!");
// Sleep for a moment to guarantee Thread 1 has time to lock Resource A
thread::sleep(Duration::from_millis(10));
println!("Thread 2: Trying to lock Resource A... (Waiting)");
let _guard_a = a_clone2.lock().unwrap(); // Stalled forever here
println!("Thread 2: Successfully locked Resource A!");
});
// 4. Wait for both threads (Spoiler: They will never finish)
handle1.join().unwrap();
handle2.join().unwrap();
println!("Program finished successfully!"); // This line will never execute
}