异步代码里调用阻塞函数会怎样?影响有多大?阻塞多少个任务才会出问题?怎么修?这篇在一个 4 线程的 tokio 运行时里,把阻塞任务数从 0 增加到 6,量出延迟的跳变点,再验证 spawn_blocking 与 block_in_place。
0 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 6 ms
1 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 5 ms
2 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 5 ms
3 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 3 ms
4 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 260 ms
6 个阻塞任务 / 4 个工作线程:主任务 sleep(10 ms) 实际晚醒了约 269 mstokio 的调度见Tokio 任务调度;手写执行器中的同类现象见Async Runtime 做了什么。
6 个 spawn_blocking 任务同时在跑:主任务 sleep(10 ms) 晚醒了约 3 ms
2 个 block_in_place 任务各阻塞 300 ms(运行时只配了 2 个工作线程):主任务 sleep(10 ms) 晚醒了约 5 ms thread 'main' (7226321) panicked at src/main.rs:2:19: can call blocking only when running on the multi-threaded runtime note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4 个 200 ms 的纯计算任务占满 4 个工作线程:主任务的 sleep(10 ms) 实际用了约 178 ms
并行计算见Rayon 并行迭代。