diff --git a/G-concurrency/deadlock.rs b/G-concurrency/deadlock.rs new file mode 100644 index 0000000..090bdd1 --- /dev/null +++ b/G-concurrency/deadlock.rs @@ -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 +} \ No newline at end of file