From 5ca2714c56b6b58e422a220bb96995fe1b720ac3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 6 Jul 2022 22:04:49 -0400 Subject: [PATCH] `spawn_blocking`: Expand on cancellation a bit I was looking at these docs again and I was thinking the "cannot be cancelled" is misleading; let's talk about approaches to do so. --- tokio/src/task/blocking.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tokio/src/task/blocking.rs b/tokio/src/task/blocking.rs index 5fe358f3e50..0fd2407d283 100644 --- a/tokio/src/task/blocking.rs +++ b/tokio/src/task/blocking.rs @@ -102,8 +102,17 @@ cfg_rt! { /// their own. If you want to spawn an ordinary thread, you should use /// [`thread::spawn`] instead. /// - /// Closures spawned using `spawn_blocking` cannot be cancelled. When you shut - /// down the executor, it will wait indefinitely for all blocking operations to + /// Closures spawned using `spawn_blocking` cannot be cancelled abruptly; there + /// is no standard low level API to cause a thread to stop running. However, + /// a useful pattern is to pass some form of "cancellation token" into + /// the thread. This could be an [`AtomicBool`], and inner loops in the + /// thread check the boolean periodically. Another approach is to + /// have the thread primarily read from a channel, and to exit when + /// the channel closes; assuming the sender side of the channel is dropped + /// when cancellation occurs, this will cause the receiver thread to exit + /// soon after as well. + /// + /// When you shut down the executor, it will wait indefinitely for all blocking operations to /// finish. You can use [`shutdown_timeout`] to stop waiting for them after a /// certain timeout. Be aware that this will still not cancel the tasks — they /// are simply allowed to keep running after the method returns. @@ -140,6 +149,7 @@ cfg_rt! { /// [`thread::spawn`]: fn@std::thread::spawn /// [`shutdown_timeout`]: fn@crate::runtime::Runtime::shutdown_timeout /// [bridgesync]: https://tokio.rs/tokio/topics/bridging + /// [`AtomicBool`]: https://doc.rust-lang.org/core/sync/atomic/struct.AtomicBool.html /// /// # Examples ///