How to change data in the `Arc`?

use tokio::time::{self, Duration, sleep};
use tokio::sync::mpsc::channel;
use std::sync::Arc;

struct Person{
    stud: Arc<Student>,
}

struct Student{
    age:i8
}

impl Person{

    async fn interval_output(&mut self){
        let mut interval = time::interval(Duration::from_secs(2));
        let (tx, mut rx) = channel(1);
        let stu = self.stud.clone();
        tokio::spawn(async move{
           sleep(Duration::from_secs(10)).await;
           let _ = tx.send(1).await;
        });
        tokio::spawn(async move{
            loop{
                let s = stu.clone();
                tokio::select!{
                    _ = interval.tick() => {
                        println!("inside loop");
                        s.age +=1;
                    },
                    Some(_) = rx.recv() => {
                        break;
                    }
                }
            }
        });
    }
}


#[tokio::main]
async fn main(){
    let p = Person{
        stud: Arc::new(Student{
            age:1
        }),
    };
    p.interval_output().await;
}

When I run the code, it shows trait DerefMut is required to modify through a dereference, but it is not implemented for Arc<Student>.

Use an Arc<Mutex<_>> or Arc<RwLock<_>> or the like. Citing the docs:

Shared references in Rust disallow mutation by default, and Arc is no exception: you cannot generally obtain a mutable reference to something inside an Arc . If you need to mutate through an Arc , use Mutex , RwLock , or one of the Atomic types.

3 Likes

Also, if you're interested in Atomics (which is a large subject), jonhoo has a great video on it: Crust of Rust: Atomics and Memory Ordering - YouTube.