Skip to content

Latest commit

 

History

History
42 lines (37 loc) · 1.54 KB

futures_select_all.md

File metadata and controls

42 lines (37 loc) · 1.54 KB

模拟一个应用场景,最多 5 个工作线程或者连接池最多五个长连接

select_all 可以同时 await 一个数组的 future,其中一个 Future 完成时,返回 (Future::Output, index, remain)

可以将工作线程的任务或者连接池请求队列看成一个数组,然后滑动宽度为 5 的窗口去执行

const NUM_WORKERS: usize = 5;
async fn do_job(job_id: usize) -> usize {
    println!("doing job {job_id}");
    if rand::random::<bool>() {
        sleep(Duration::from_secs(1)).await;
    } else {
        sleep(Duration::from_secs(2)).await;
    }
    job_id
}
#[tokio::main]
async fn main() {
    let mut jobs = (0..12).collect::<std::collections::VecDeque<usize>>();
    let mut futs = Vec::new();
    while let Some(job_id) = jobs.pop_front() {
        if futs.len() < NUM_WORKERS {
            futs.push(do_job(job_id).boxed());
            continue;
        }
        let futs_ = std::mem::take(&mut futs);
        let (fut_ret, _index, remain) = futures::future::select_all(futs_).await;
        // println!("done  job {fut_ret}");
        futs = remain;
        futs.push(do_job(job_id).boxed());
    }
}
当协程退出或 IO 阻塞时主动让出占用的计算资源,供其他 Goroutine 使用,这是典型的协作式调度
但在特定情况下(协程长时间占用计算资源),runtime 会将其强制中断,让其他 Goroutine 都能有机会得到执行
主要采用协作式调度,而抢占式调度仅在特定情况下作为辅助