1
votes

How can I print the values of a Vec that is encapsulated by a Mutex and Arc? I'm really new to Rust, so I'm not sure if I am phrasing this well.

This is the code I have, loosely based on the documentation.

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

fn main() {
    let data = Arc::new(Mutex::new(vec![104, 101, 108, 108, 111]));

    for i in 0..2 {
        let data = data.clone();
        thread::spawn(move || {
            let mut data = data.lock().unwrap();
            data[i] += 1;
        });
    }

    println!("{:?}", String::from_utf8(data).unwrap());
    thread::sleep_ms(50);
}

The error that the compiler gives me:

$ rustc datarace_fixed.rs datarace_fixed.rs:14:37: 14:41 error: mismatched types: expected collections::vec::Vec<u8>, found alloc::arc::Arc<std::sync::mutex::Mutex<collections::vec::Vec<_>>> (expected struct collections::vec::Vec, found struct alloc::arc::Arc) [E0308] datarace_fixed.rs:14 println!("{:?}", String::from_utf8(data).unwrap());

1

1 Answers

5
votes

To work with a Mutex value you have to lock the Mutex, just like you do in the spawned threads. (playpen):

let data = data.lock().unwrap();
println!("{:?}", String::from_utf8(data.clone()).unwrap());

Note that String::from_utf8 consumes the vector (in order to wrap it in a String without extra allocations), which is obvious from it taking a value vec: Vec<u8> and not a reference. Since we aren't ready to relinquish our hold on data we have to clone it when using this method.

A cheaper alternative would be to use the slice-based version of from_utf8 (playpen):

let data = data.lock().unwrap();
println!("{:?}", from_utf8(&data).unwrap());