Skip to content

Proposed data-race code does not compile #5

@sleberknight

Description

@sleberknight

In the data-race example, the commented out code that is shown as the fix does not compile:

// Mutex that protects the data vector, and then we spawn three threads 
//that each acquire a lock on the mutex and modify an element of the vector.

use std::sync::Mutex;
use std::thread;

fn main() {
    let data = Mutex::new(vec![1, 2, 3]);

    let handles: Vec<_> = (0..3).map(|i| {
        let data = data.clone();
        thread::spawn(move || {
            let mut data = data.lock().unwrap();
            data[i] += 1;
        })
    }).collect();

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{:?}", data);
}

This fails to compile with the error:

error[E0599]: no method named `clone` found for struct `std::sync::Mutex<T>` in the current scope
   --> src/main.rs:13:25
    |
 13 |         let data = data.clone();
    |                         ^^^^^ method not found in `std::sync::Mutex<Vec<{integer}>>`
    |
note: the method `clone` exists on the type `Vec<{integer}>`
   --> /Users/sleberkn/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/clone.rs:236:5
    |
236 |     fn clone(&self) -> Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
help: use `.lock().unwrap()` to borrow the `Vec<{integer}>`, blocking the current thread until it can be acquired
    |
 13 |         let data = data.lock().unwrap().clone();
    |                        ++++++++++++++++

The reason is that Mutex does not implement Clone.

Claude tells me that the correct fix is to use Arc to wrap the Mutex:

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

fn main() {
    let data = Arc::new(Mutex::new(vec![1, 2, 3]));

    let mut handles = vec![];

    for i in 0..3 {
        let data_clone = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let mut d = data_clone.lock().unwrap();
            d[i] += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{:?}", data);  // [2, 3, 4]
}

When run I get the output:

Mutex { data: [2, 3, 4], poisoned: false, .. }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions