-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tokio::spawn_blocking has slightly misleading documentation #2143
Comments
I think the documentation should also note whether there is a limit on the number of tasks waiting to be executed if |
This seem to be the relevant sections: tokio/tokio/src/runtime/blocking/pool.rs Lines 47 to 54 in 5bf78d7
tokio/tokio/src/runtime/blocking/pool.rs Lines 129 to 192 in 5bf78d7
The waiting tasks seem to be queued in a |
Current behaviour appears to be to panic when exceeding the pool, running this example #[tokio::main]
async fn main() {
for i in 0..10000 {
eprintln!("Running {}", i);
tokio::task::spawn_blocking(|| std::thread::sleep(std::time::Duration::from_secs(1)));
}
} logs
backtrace
|
@Nemo157 I can't reproduce what you're seeing locally. I think this is just a limitation of the playground. They probably use cgroups or something similar to limit the amount of threads a single program can create. |
fn main() {
let mut runtime = tokio::runtime::Builder::new()
.threaded_scheduler()
.max_threads(20)
.build().expect("Failed to build runtime.");
runtime.block_on(spawn_blocking());
}
async fn spawn_blocking() {
for i in 0..100 {
eprintln!("Spawning {}", i);
tokio::task::spawn_blocking(move ||{
println!("Running {}", i);
std::thread::sleep(std::time::Duration::from_secs(1));
println!("Finished {}", i);
});
}
} This shows that if the amount of threads is limited manually, Tasks are spawned immediately and queued to be run once one of the threads becomes available. |
Hmm, yes, running locally with a bit more debugging I see that it's running ~500 of the blocking tasks at a time and completes successfully. It took a while to figure out how to get the info, but I confirmed that the playground has a 512 process limit in cgroups. It seems like Tokio should handle this case gracefully as well, but should be a separate issue. |
I ran into the same confusion between the documentation and the source code. Thanks for pointing this out @FSMaxB-dooshop ! I have a compute intensive workload too and having two separate run times, a basic_scheduler runtime for IO operations and a threaded_scheduler capped at the number of CPU threads - 1 seems like it might be the way to go for me. I am curious, what setup did you go with? |
If anyone is up for writing a documentation PR that addresses this on |
The initial spawn_blocking documentation was unclear. This PR attempts to fix that. Fixes tokio-rs#2143
Version
tokio 0.2.9
Platform
Linux 5.4.13 amd64
Description
https://docs.rs/tokio/0.2.9/tokio/task/fn.spawn_blocking.html
This is missing the information that this thread pool for blocking tasks is going to spawn up to
max_threads - core_threads
(~512) new threads on calls tospawn_blocking
if no idle worker thread is available.When I read this section in the documentation I implicitly assumed a similar behavior to the default runtime for futures, that has as many threads as the system has cores, but that doesn't seem to be the case looking at the source code.
In my case I was using it for heavy computation. I previously used
tokio-threadpool
but on porting to 0.2 I switched tospawn_blocking
resulting in a hugely increased system load.Knowing this I can create a separate runtime for my compute intensive workloads, but adding this information to the documentation would be helpful.
I can try to make a documentation PR if you want, but I'm writing this issue first because I'm not 100% confident in my documentation writing skills and if I got all the details correct.
The text was updated successfully, but these errors were encountered: