Don't get arc + rwlock + threads to compile

Hi, I don't know what to do to get it compiled.

The code is:

use std::{
    sync::{Arc, RwLock},
    thread,
    time::Duration,
};

trait Print {
    fn print(&self);
}

struct A {
    a: i32,
}

struct B {
    b: i32,
}

impl Print for A {
    fn print(&self) {
        println!("a = {0}", self.a);
    }
}

impl Print for B {
    fn print(&self) {
        println!("b = {0}", self.b);
    }
}

type Printable = Arc<RwLock<dyn Print>>;

fn main() {
    let a = Arc::new(RwLock::new(A { a: 1 }));
    let a1 = a.clone();
    let b = Arc::new(RwLock::new(B { b: 2 }));
    let b1 = b.clone();

    let mut c: Vec<Printable> = Vec::new();
    c.push(a1 as Printable);
    c.push(b1 as Printable);

    // change the values in a background thread
    thread::spawn(move || loop {
        {
            let mut a = a.write().unwrap();
            a.a += 1;
            let mut b = b.write().unwrap();
            b.b += 1;
        }
        thread::sleep(Duration::from_secs(1));
    });

    // read the values in another background thread
    thread::spawn(move || loop {
        {
            for p in c {
                let p = p.read().unwrap();
                p.print();
            }
        }
        thread::sleep(Duration::from_millis(500));
    });
    thread::sleep(Duration::from_secs(3));
}

Error Message begins with:

error[E0277]: `(dyn Print + 'static)` cannot be sent between threads safely
   --> src/main.rs:55:19
    |
55  |       thread::spawn(move || loop {
    |  _____-------------_^
    | |     |
    | |     required by a bound introduced by this call
56  | |         {
57  | |             for p in c {
58  | |                 let p = p.read().unwrap();
...   |
62  | |         thread::sleep(Duration::from_millis(500));
63  | |     });
    | |_____^ `(dyn Print + 'static)` cannot be sent between threads safely

Thx for any hint or help!

Adding Send and Sync bounds on dyn Print runs on the playground:

use std::{
    sync::{Arc, RwLock},
    thread,
    time::Duration,
};

trait Print {
    fn print(&self);
}

struct A {
    a: i32,
}

struct B {
    b: i32,
}

impl Print for A {
    fn print(&self) {
        println!("a = {0}", self.a);
    }
}

impl Print for B {
    fn print(&self) {
        println!("b = {0}", self.b);
    }
}

type Printable = Arc<RwLock<dyn Print + Send + Sync>>;

fn main() {
    let a = Arc::new(RwLock::new(A { a: 1 }));
    let a1 = a.clone();
    let b = Arc::new(RwLock::new(B { b: 2 }));
    let b1 = b.clone();

    let mut c: Vec<Printable> = Vec::new();
    c.push(a1 as Printable);
    c.push(b1 as Printable);

    // change the values in a background thread
    thread::spawn(move || loop {
        {
            let mut a = a.write().unwrap();
            a.a += 1;
            let mut b = b.write().unwrap();
            b.b += 1;
        }
        thread::sleep(Duration::from_secs(1));
    });

    // read the values in another background thread
    thread::spawn(move || loop {
        {
            for p in &c {
                let p = p.read().unwrap();
                p.print();
            }
        }
        thread::sleep(Duration::from_millis(500));
    });
    thread::sleep(Duration::from_secs(3));
}
4 Likes

Thank you for the quick help. Now it compiles and works as expected!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.