use core::time;
use std::sync::Arc;
use tokio::sync::Mutex;
#[tokio::main]
async fn main() {
let buf_str = Arc::new(Mutex::new(Vec::<String>::new()));
let buf_num = Arc::new(Mutex::new(Vec::<u8>::new()));
// 一定要先clone,使其引用计数+1
let buf1 = buf_str.clone();
let buf2 = buf_num.clone();
// 线程1
let thread1 = tokio::spawn(async move {
for i in 0..10 {
tokio::time::sleep(time::Duration::from_secs(1)).await;
buf_str.lock().await.push(String::from("round:"));
buf_num.lock().await.push(i);
}
});
// 线程2
let thread2 = tokio::spawn(async move {
for i in 0..10 {
tokio::time::sleep(time::Duration::from_secs(1)).await;
println!("buf_str={:?}", buf1);
if i == 5 {
buf1.lock().await.clear();
}
println!("buf_num={:?}", buf2);
}
});
thread1.await.unwrap();
thread2.await.unwrap();
}
代码中,我们创建了两个线程thread1和thread2,这两个线程共享了两个内存空间,分别是buf_str,buf_num。
对于这些用于多线程共享的变量,我们要用Arc<Mutex<T>>来创建。Arc<T>是用于共享所有权,而Mutex<T>是一个支持跨线程安全共享可变变量的容器。
Arc的全名就是:Atomically Reference Counted,即原子引用计数。因此想要在线程中共享避免value moved的错误,必须先将原子引用计数+1,即进行clone。
最后程序输出如下所示:
buf_str=Mutex { data: [] }
buf_num=Mutex { data: [0] }
buf_str=Mutex { data: ["round:"] }
buf_num=Mutex { data: [0] }
buf_str=Mutex { data: ["round:", "round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2] }
buf_str=Mutex { data: ["round:", "round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2, 3] }
buf_str=Mutex { data: ["round:", "round:", "round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2, 3, 4] }
buf_str=Mutex { data: ["round:", "round:", "round:", "round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2, 3, 4, 5] }
buf_str=Mutex { data: [] }
buf_num=Mutex { data: [0, 1, 2, 3, 4, 5, 6] }
buf_str=Mutex { data: ["round:"] }
buf_num=Mutex { data: [0, 1, 2, 3, 4, 5, 6, 7] }
buf_str=Mutex { data: ["round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2, 3, 4, 5, 6, 7, 8] }
buf_str=Mutex { data: ["round:", "round:", "round:"] }
buf_num=Mutex { data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }
可以看到线程的并发运行,以及线程2对buf1的清空结果。
网友评论