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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions