diff --git a/tokio/src/task/blocking.rs b/tokio/src/task/blocking.rs index e4fe254a087..c0b1d2b7c12 100644 --- a/tokio/src/task/blocking.rs +++ b/tokio/src/task/blocking.rs @@ -111,9 +111,22 @@ cfg_rt! { /// still spawn additional threads for blocking operations. The basic /// scheduler's single thread is only used for asynchronous code. /// + /// # Related APIs and patterns for bridging asynchronous and blocking code + /// + /// In simple cases, it is sufficient to have the closure accept input + /// parameters at creation time and return a single value (or struct/tuple, etc.). + /// + /// For more complex situations in which it is desirable to stream data to or from + /// the synchronous context, the [`channel APIs`] have [`crate::sync::mpsc::Sender::blocking_send`] and + /// [`crate::sync::mpsc::Receiver::blocking_recv`] that support being called + /// from the spawned thread's blocking context. You may also find it useful + /// to wrap the channels in e.g. [`ReceiverStream`]. + /// /// [`Builder`]: struct@crate::runtime::Builder /// [blocking]: ../index.html#cpu-bound-tasks-and-blocking-code /// [rayon]: https://docs.rs/rayon + /// [`channel APIs`]: crate::sync::mpsc + /// [`ReceiverStream`]: https://docs.rs/tokio-stream/0.1/tokio_stream/wrappers/struct.ReceiverStream.html /// [`thread::spawn`]: fn@std::thread::spawn /// [`shutdown_timeout`]: fn@crate::runtime::Runtime::shutdown_timeout /// @@ -132,6 +145,29 @@ cfg_rt! { /// # Ok(()) /// # } /// ``` + /// + /// ``` + /// use tokio::task; + /// use tokio::sync::mpsc; + /// + /// # async fn docs() { + /// let (tx, mut rx) = mpsc::channel(2); + /// let start = 5; + /// let worker = task::spawn_blocking(move || { + /// for x in 0..10 { + /// // Stand in for complex computation + /// tx.blocking_send(start + x).unwrap(); + /// } + /// }); + /// + /// let mut acc = 0; + /// while let Some(v) = rx.recv().await { + /// acc += v; + /// } + /// assert_eq!(acc, 45); + /// worker.await.unwrap(); + /// # } + /// ``` #[cfg_attr(tokio_track_caller, track_caller)] pub fn spawn_blocking(f: F) -> JoinHandle where