use std::error::Error;
use tokio::sync::Semaphore;
// 模拟网络请求
async fn mock_network_request(task_id: u32) -> Result<(), Box<dyn Error>> {
println!("Task {} started", task_id);
// 这里可以替换为实际的网络请求逻辑
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("Task {} completed", task_id);
Ok(())
}
#[tokio::main]
async fn main() {
let semaphore = Semaphore::new(10);
let mut tasks = Vec::new();
for i in 0..100 {
let permit = semaphore.acquire().await.expect("Failed to acquire permit");
let task = tokio::spawn(async move {
let result = mock_network_request(i).await;
drop(permit); // 任务完成后释放信号量
result
});
tasks.push(task);
}
for task in tasks {
if let Err(e) = task.await {
eprintln!("Task failed: {}", e);
}
}
}
- 引入必要的库:代码中使用了
tokio::sync::Semaphore
来控制并发数量,所以需要引入 tokio
库。
- 模拟网络请求函数:
mock_network_request
函数模拟了一个网络请求,打印开始和结束信息,并使用 tokio::time::sleep
模拟请求耗时。
- 主函数:
- 创建一个最大许可数为10的
Semaphore
。
- 遍历100次,每次获取一个信号量
permit
,并创建一个异步任务。任务中先执行模拟网络请求,请求完成后释放 permit
。
- 等待所有任务完成,并处理任务执行过程中可能出现的错误,打印错误信息。