功能说明
示例用 Arc<Semaphore> 在多个 spawned 任务之间共享并发上限。每个任务先调用 acquire_owned() 拿到许可,许可在任务结束前一直持有,因此同一时刻最多只有 Semaphore::new(2) 个任务进入临界区。所有任务交给 JoinSet 管理,主任务通过 join_next 收集结果并排序输出。
关键代码
let _permit = permits.acquire_owned().await.expect("semaphore closed");
sleep(Duration::from_millis(30)).await;
id * id
绑定到 _permit 而不是 _,许可才会活到任务结束;_ 会立即丢弃,限流失效。
使用注意
acquire_owned需要Arc<Semaphore>,返回的许可拥有所有权,适合在'static任务中持有。- 任务 panic 时许可随栈展开释放,不会永久占用。
JoinSet只保证收集结果,不保证完成顺序;示例最后排序以获得稳定输出。- 许可数量应按下游承载能力设置,过小会排队,过大会压垮依赖。
- 如果需要等待超时,可在
acquire_owned外层再包tokio::time::timeout。
验证方式
示例启动 6 个任务、上限 2、每个任务 30 毫秒,总耗时约 90 毫秒,输出排序后为 [0, 1, 4, 9, 16, 25]。把上限改为 1 可观察耗时变为约 180 毫秒。