MST

星途 面试题库

面试题:Rust async/await与并发控制

假设有100个异步任务,每个任务模拟一个网络请求(可以简单打印开始和结束信息),但是系统资源有限,同一时间只能允许10个任务并发执行。请使用Rust的`async/await`结合合适的并发控制机制(如`tokio::sync::Semaphore`)来实现这个需求,并且要确保所有任务最终都能执行完成,同时展示如何处理任务执行过程中的错误。
24.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
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);
        }
    }
}
  1. 引入必要的库:代码中使用了 tokio::sync::Semaphore 来控制并发数量,所以需要引入 tokio 库。
  2. 模拟网络请求函数mock_network_request 函数模拟了一个网络请求,打印开始和结束信息,并使用 tokio::time::sleep 模拟请求耗时。
  3. 主函数
    • 创建一个最大许可数为10的 Semaphore
    • 遍历100次,每次获取一个信号量 permit,并创建一个异步任务。任务中先执行模拟网络请求,请求完成后释放 permit
    • 等待所有任务完成,并处理任务执行过程中可能出现的错误,打印错误信息。