w3resource

Rust Deadlock Prevention with Mutexes

Rust Threads and Synchronization: Exercise-9 with Solution

Write a Rust program that demonstrates deadlock and how to prevent it using mutexes and locks.

Sample Solution:

Rust Code:

use std::thread;
use std::sync::{Mutex, Arc};

fn main() {
    // Create two mutexes for shared resources
    let resource1 = Arc::new(Mutex::new(()));
    let resource2 = Arc::new(Mutex::new(()));

    // Clone Arc pointers for each thread
    let resource1_clone = Arc::clone(&resource1);
    let resource2_clone = Arc::clone(&resource2);

    // Create two threads that acquire resources in opposite order
    let thread1 = thread::spawn(move || {
        // Lock resource1
        let _lock1 = resource1.lock().unwrap();
        println!("Thread 1 acquired resource 1");

        // Sleep to simulate some work
        thread::sleep(std::time::Duration::from_millis(100));

        // Lock resource2
        let _lock2 = resource2_clone.lock().unwrap(); // Lock in the same order
        println!("Thread 1 acquired resource 2");
    });

    let thread2 = thread::spawn(move || {
        // Lock resource2
        let _lock2 = resource2.lock().unwrap();
        println!("Thread 2 acquired resource 2");

        // Sleep to simulate some work
        thread::sleep(std::time::Duration::from_millis(100));

        // Lock resource1
        let _lock1 = resource1_clone.lock().unwrap(); // Lock in the same order
        println!("Thread 2 acquired resource 1");
    });

    // Wait for threads to finish
    thread1.join().unwrap();
    thread2.join().unwrap();

    println!("Program finished");
}

Output:

Thread 2 acquired resource 2
Thread 1 acquired resource 1

Explanation:

In the exercise above,

  • Create two mutexes (resource1 and resource2) to represent shared resources.
  • Clone Arc pointers for each mutex so that each thread can have its own copy of the mutex.
  • Create two threads (thread1 and thread2) that attempt to lock the mutexes in opposite order.
  • Each thread locks one resource and then attempts to lock the other resource, which leads to a deadlock because they are holding one resource and waiting for the other.
  • To prevent deadlock, we ensure that threads always acquire resources in the same order. In the modified code, both threads always lock 'resource1' before attempting to lock 'resource2', ensuring that they acquire resources in the same order and preventing deadlock.

Rust Code Editor:

Previous: Rust Parallel Sum Calculation with Threads.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.