I’m getting some unexpected results with tokio::spawn_blocking
and wanted to open a post to discuss it.
I wanted an example to show how spawn_blocking
and spawn
work and when I should use one over the other but I’m getting code that doesn’t halt with tokio::spawn_blocking
.
1 Spawn fib
and run print to stdout in main
:
let r = tokio::task::spawn(async { fib(NUMBER) });
while !r.is_finished() {
let s: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(1000)
.map(char::from)
.collect();
println!("{}", s);
}
let r = r.await?;
78.52s user 2.01s system 198% cpu 40.498 total
2 Spawn fib
and sleep in main
:
let r = tokio::task::spawn(async { fib(NUMBER) });
while !r.is_finished() {
tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
}
let r = r.await?;
39.34s user 0.03s system 99% cpu 39.521 total
3 Spawn blocking fib
and print to stdout in main:
let r = tokio::task::spawn_blocking(|| fib(NUMBER));
while !r.is_finished() {
let s: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(1000)
.map(char::from)
.collect();
println!("{}", s);
}
let r = r.await?;
78.41s user 2.04s system 199% cpu 40.325 total
4 Spawn blocking fib
and sleep in main
:
let r = tokio::task::spawn_blocking(|| fib(NUMBER));
while !r.is_finished() {
tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
}
let r = r.await?;
println!("{r}");
39.18s user 0.03s system 99% cpu 39.347 total
These are results that make sense to me so far.
The following results don’t make sense to me:
5 Spawn sleep loop and call fib
in main
let r = tokio::task::spawn(async {
loop {
tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
}
});
fib(NUMBER);
r.abort();
39.16s user 0.02s system 99% cpu 39.299 total
6 Spawn print loop and call fib
in main
let r = tokio::task::spawn(async {
loop {
let s: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(1000)
.map(char::from)
.collect();
println!("{}", s);
}
});
fib(NUMBER);
r.abort();
7 Spawn blocking sleep loop and call fib
in main
let r = tokio::task::spawn_blocking(|| loop {
std::thread::sleep(std::time::Duration::from_millis(20));
});
fib(NUMBER);
r.abort();
DOES NOT HALT
8 Spawn blocking print loop and call fib
in main
let r = tokio::task::spawn_blocking(|| loop {
let s: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(1000)
.map(char::from)
.collect();
println!("{}", s);
});
fib(NUMBER);
r.abort();
DOES NOT HALT
Here’s a link to the source code if someone wants to play around with it: