summaryrefslogtreecommitdiffstats
path: root/tokio/src/task
diff options
context:
space:
mode:
authorAlice Ryhl <alice@ryhl.io>2020-04-24 16:16:46 +0200
committerGitHub <noreply@github.com>2020-04-24 10:16:46 -0400
commit3572ba5a7b15b83a4b25b21395e85425622ec0e6 (patch)
treec35268169ea185a9c2eac90e73c85a79c5dd3829 /tokio/src/task
parentd8139fef7a555f99adaa37e139787d26e24daba3 (diff)
task: update doc on spawn_blocking and block_in_place (#2436)
Diffstat (limited to 'tokio/src/task')
-rw-r--r--tokio/src/task/blocking.rs73
1 files changed, 62 insertions, 11 deletions
diff --git a/tokio/src/task/blocking.rs b/tokio/src/task/blocking.rs
index f9be1ead..0ef60535 100644
--- a/tokio/src/task/blocking.rs
+++ b/tokio/src/task/blocking.rs
@@ -1,20 +1,37 @@
use crate::task::JoinHandle;
cfg_rt_threaded! {
- /// Runs the provided blocking function without blocking the executor.
+ /// Runs the provided blocking function on the current thread without
+ /// blocking the executor.
///
/// In general, issuing a blocking call or performing a lot of compute in a
/// future without yielding is not okay, as it may prevent the executor from
- /// driving other futures forward. If you run a closure through this method,
- /// the current executor thread will relegate all its executor duties to another
- /// (possibly new) thread, and only then poll the task. Note that this requires
- /// additional synchronization.
+ /// driving other futures forward. This function runs the closure on the
+ /// current thread by having the thread temporarily cease from being a core
+ /// thread, and turns it into a blocking thread. See the [CPU-bound tasks
+ /// and blocking code][blocking] section for more information.
///
- /// # Note
+ /// Although this function avoids starving other independently spawned
+ /// tasks, any other code running concurrently in the same task will be
+ /// suspended during the call to `block_in_place`. This can happen e.g. when
+ /// using the [`join!`] macro. To avoid this issue, use [`spawn_blocking`]
+ /// instead.
///
- /// This function can only be called from a spawned task when working with
- /// the [threaded scheduler](https://docs.rs/tokio/0.2.10/tokio/runtime/index.html#threaded-scheduler).
- /// Consider using [tokio::task::spawn_blocking](https://docs.rs/tokio/0.2.10/tokio/task/fn.spawn_blocking.html).
+ /// Note that this function can only be used on the [threaded scheduler].
+ ///
+ /// Code running behind `block_in_place` cannot be cancelled. 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.
+ ///
+ /// [blocking]: ../index.html#cpu-bound-tasks-and-blocking-code
+ /// [threaded scheduler]: fn@crate::runtime::Builder::threaded_scheduler
+ /// [`spawn_blocking`]: fn@crate::task::spawn_blocking
+ /// [`join!`]: ../macro.join.html
+ /// [`thread::spawn`]: fn@std::thread::spawn
+ /// [`shutdown_timeout`]: fn@crate::runtime::Runtime::shutdown_timeout
///
/// # Examples
///
@@ -39,9 +56,43 @@ cfg_rt_threaded! {
cfg_blocking! {
/// Runs the provided closure on a thread where blocking is acceptable.
///
- /// More information about the blocking threads is available at [CPU-bound tasks and blocking code][blocking].
+ /// In general, issuing a blocking call or performing a lot of compute in a
+ /// future without yielding is not okay, as it may prevent the executor from
+ /// driving other futures forward. This function runs the provided closure
+ /// on a thread dedicated to blocking operations. See the [CPU-bound tasks
+ /// and blocking code][blocking] section for more information.
+ ///
+ /// Tokio will spawn more blocking threads when they are requested through
+ /// this function until the upper limit configured on the [`Builder`] is
+ /// reached. This limit is very large by default, because `spawn_blocking` is
+ /// often used for various kinds of IO operations that cannot be performed
+ /// asynchronously. When you run CPU-bound code using `spawn_blocking`, you
+ /// should keep this large upper limit in mind; to run your CPU-bound
+ /// computations on only a few threads, you should use a separate thread
+ /// pool such as [rayon] rather than configuring the number of blocking
+ /// threads.
+ ///
+ /// This function is intended for non-async operations that eventually
+ /// finish on 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 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.
+ ///
+ /// Note that if you are using the [basic scheduler], this function will
+ /// still spawn additional threads for blocking operations. The basic
+ /// scheduler's single thread is only used for asynchronous code.
///
- /// [blocking]: ../index.html#cpu-bound-tasks-and-blocking-code
+ /// [`Builder`]: struct@crate::runtime::Builder
+ /// [blocking]: ../index.html#cpu-bound-tasks-and-blocking-code
+ /// [rayon]: https://docs.rs/rayon
+ /// [basic scheduler]: fn@crate::runtime::Builder::basic_scheduler
+ /// [`thread::spawn`]: fn@std::thread::spawn
+ /// [`shutdown_timeout`]: fn@crate::runtime::Runtime::shutdown_timeout
///
/// # Examples
///