- 设计并实现异步程序结构
- 使用
Arc
(原子引用计数)和Mutex
(互斥锁)来安全地共享和修改布尔变量。Arc
用于在多个线程间共享数据,Mutex
用于保护数据不被并发访问。
- 下面是具体的代码实现:
use std::sync::{Arc, Mutex};
use futures::stream::StreamExt;
use tokio::task;
#[tokio::main]
async fn main() {
let should_continue = Arc::new(Mutex::new(true));
let should_continue_clone = should_continue.clone();
// 创建多个异步任务
let task1 = task::spawn(async move {
while *should_continue_clone.lock().unwrap() {
// 模拟从网络获取数据并处理
println!("Task 1 is working...");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
}
println!("Task 1 stopped.");
});
let should_continue_clone = should_continue.clone();
let task2 = task::spawn(async move {
while *should_continue_clone.lock().unwrap() {
println!("Task 2 is working...");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
}
println!("Task 2 stopped.");
});
// 模拟一段时间后改变共享状态
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
*should_continue.lock().unwrap() = false;
// 等待任务完成
task1.await.unwrap();
task2.await.unwrap();
}
- 处理并发问题
- 通过
Mutex
来确保在同一时间只有一个任务可以访问和修改should_continue
变量。当一个任务想要读取或修改should_continue
时,它需要先获取Mutex
的锁。如果锁已经被其他任务持有,该任务会被阻塞,直到锁被释放。
Arc
确保了在多个任务间安全地共享Mutex
包装的布尔变量,因为Arc
提供了线程安全的引用计数,只有当所有的引用都被释放后,数据才会被销毁。
- Rust布尔类型在内存模型和并发控制方面的特性
- 内存模型:Rust的布尔类型
bool
是一个简单的基本类型,在内存中通常占用1个字节。它具有固定的内存布局,这使得在不同的平台上表现一致。
- 并发控制:布尔类型本身不具备内置的并发控制机制。然而,当与
Mutex
等同步原语结合使用时,可以在并发环境中安全地使用。由于bool
是Copy类型,它可以在Mutex
内部被安全地复制和修改,只要获取了Mutex
的锁,就可以像操作普通的布尔变量一样操作它。这种方式保证了在多线程环境下对布尔变量的访问是线程安全的,避免了数据竞争等并发问题。