mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-24 00:00:11 +02:00
doc: expand on runtime / spawn docs (#1914)
This commit is contained in:
@@ -161,6 +161,16 @@
|
||||
//! This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a
|
||||
//! shorthand, [`Builder::enable_all`] enables both resource drivers.
|
||||
//!
|
||||
//! ## Lifetime of spawned threads
|
||||
//!
|
||||
//! The runtime may spawn threads depending on its configuration and usage. The
|
||||
//! threaded scheduler spawns threads to schedule tasks and calls to
|
||||
//! `spawn_blocking` spawn threads to run blocking operations.
|
||||
//!
|
||||
//! While the `Runtime` is active, threads may shutdown after periods of being
|
||||
//! idle. Once `Runtime` is dropped, all runtime threads are forcibly shutdown.
|
||||
//! Any tasks that have not yet completed will be dropped.
|
||||
//!
|
||||
//! [tasks]: crate::task
|
||||
//! [driver]: crate::io::driver
|
||||
//! [executor]: https://tokio.rs/docs/internals/runtime-model/#executors
|
||||
|
||||
@@ -12,6 +12,10 @@ doc_rt_core! {
|
||||
/// different thread to be executed. The specifics depend on the current
|
||||
/// [`Runtime`](crate::runtime::Runtime) configuration.
|
||||
///
|
||||
/// There is no guarantee that a spawned task will execute to completion.
|
||||
/// When a runtime is shutdown, all outstanding tasks are dropped,
|
||||
/// regardless of the lifecycle of that task.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In this example, a server is started and `spawn` is used to start a new task
|
||||
@@ -45,6 +49,75 @@ doc_rt_core! {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called from **outside** of the Tokio runtime.
|
||||
///
|
||||
/// # Using `!Send` values from a task
|
||||
///
|
||||
/// The task supplied to `spawn` must implement `!Send`. However, it is
|
||||
/// possible to **use** `!Send` values from the task as long as they only
|
||||
/// exist between calls to `.await`.
|
||||
///
|
||||
/// For example, this will work:
|
||||
///
|
||||
/// ```
|
||||
/// use tokio::task;
|
||||
///
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// fn use_rc(rc: Rc<()>) {
|
||||
/// // Do stuff w/ rc
|
||||
/// # drop(rc);
|
||||
/// }
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() {
|
||||
/// tokio::spawn(async {
|
||||
/// // Force the `Rc` to stay in a scope with no `.await`
|
||||
/// {
|
||||
/// let rc = Rc::new(());
|
||||
/// use_rc(rc.clone());
|
||||
/// }
|
||||
///
|
||||
/// task::yield_now().await;
|
||||
/// }).await.unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This will **not** work:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use tokio::task;
|
||||
///
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// fn use_rc(rc: Rc<()>) {
|
||||
/// // Do stuff w/ rc
|
||||
/// # drop(rc);
|
||||
/// }
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() {
|
||||
/// tokio::spawn(async {
|
||||
/// let rc = Rc::new(());
|
||||
///
|
||||
/// task::yield_now().await;
|
||||
///
|
||||
/// use_rc(rc.clone());
|
||||
/// }).await.unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Holding on to a `!Send` value across calls to `.await` will result in
|
||||
/// an unfriendly compile error message similar to:
|
||||
///
|
||||
/// ```text
|
||||
/// `[... some type ...]` cannot be sent between threads safely
|
||||
/// ```
|
||||
///
|
||||
/// or:
|
||||
///
|
||||
/// ```text
|
||||
/// error[E0391]: cycle detected when processing `main`
|
||||
/// ```
|
||||
pub fn spawn<T>(task: T) -> JoinHandle<T::Output>
|
||||
where
|
||||
T: Future + Send + 'static,
|
||||
|
||||
Reference in New Issue
Block a user