async_std/task/
mod.rs

1//! Types and traits for working with asynchronous tasks.
2//!
3//! This module is similar to [`std::thread`], except it uses asynchronous tasks in place of
4//! threads.
5//!
6//! [`std::thread`]: https://doc.rust-lang.org/std/thread
7//!
8//! ## The task model
9//!
10//! An executing asynchronous Rust program consists of a collection of native OS threads, on top of
11//! which multiple stackless coroutines are multiplexed. We refer to these as "tasks".  Tasks can
12//! be named, and provide some built-in support for synchronization.
13//!
14//! Communication between tasks can be done through channels, Rust's message-passing types, along
15//! with [other forms of tasks synchronization](../sync/index.html) and shared-memory data
16//! structures. In particular, types that are guaranteed to be threadsafe are easily shared between
17//! tasks using the atomically-reference-counted container, [`Arc`].
18//!
19//! Fatal logic errors in Rust cause *thread panic*, during which a thread will unwind the stack,
20//! running destructors and freeing owned resources. If a panic occurs inside a task, there is no
21//! meaningful way of recovering, so the panic will propagate through any thread boundaries all the
22//! way to the root task. This is also known as a "panic = abort" model.
23//!
24//! ## Spawning a task
25//!
26//! A new task can be spawned using the [`task::spawn`][`spawn`] function:
27//!
28//! ```no_run
29//! use async_std::task;
30//!
31//! task::spawn(async {
32//!     // some work here
33//! });
34//! ```
35//!
36//! In this example, the spawned task is "detached" from the current task. This means that it can
37//! outlive its parent (the task that spawned it), unless this parent is the root task.
38//!
39//! The root task can also wait on the completion of the child task; a call to [`spawn`] produces a
40//! [`JoinHandle`], which implements `Future` and can be `await`ed:
41//!
42//! ```
43//! use async_std::task;
44//!
45//! # async_std::task::block_on(async {
46//! #
47//! let child = task::spawn(async {
48//!     // some work here
49//! });
50//! // some work here
51//! let res = child.await;
52//! #
53//! # })
54//! ```
55//!
56//! The `await` operator returns the final value produced by the child task.
57//!
58//! ## Configuring tasks
59//!
60//! A new task can be configured before it is spawned via the [`Builder`] type,
61//! which currently allows you to set the name for the child task:
62//!
63//! ```
64//! # #![allow(unused_must_use)]
65//! use async_std::task;
66//!
67//! # async_std::task::block_on(async {
68//! #
69//! task::Builder::new().name("child1".to_string()).spawn(async {
70//!     println!("Hello, world!");
71//! });
72//! #
73//! # })
74//! ```
75//!
76//! ## The `Task` type
77//!
78//! Tasks are represented via the [`Task`] type, which you can get in one of
79//! two ways:
80//!
81//! * By spawning a new task, e.g., using the [`task::spawn`][`spawn`]
82//!   function, and calling [`task`][`JoinHandle::task`] on the [`JoinHandle`].
83//! * By requesting the current task, using the [`task::current`] function.
84//!
85//! ## Task-local storage
86//!
87//! This module also provides an implementation of task-local storage for Rust
88//! programs. Task-local storage is a method of storing data into a global
89//! variable that each task in the program will have its own copy of.
90//! Tasks do not share this data, so accesses do not need to be synchronized.
91//!
92//! A task-local key owns the value it contains and will destroy the value when the
93//! task exits. It is created with the [`task_local!`] macro and can contain any
94//! value that is `'static` (no borrowed pointers). It provides an accessor function,
95//! [`with`], that yields a shared reference to the value to the specified
96//! closure. Task-local keys allow only shared access to values, as there would be no
97//! way to guarantee uniqueness if mutable borrows were allowed.
98//!
99//! ## Naming tasks
100//!
101//! Tasks are able to have associated names for identification purposes. By default, spawned
102//! tasks are unnamed. To specify a name for a task, build the task with [`Builder`] and pass
103//! the desired task name to [`Builder::name`]. To retrieve the task name from within the
104//! task, use [`Task::name`].
105//!
106//! [`Arc`]: ../sync/struct.Arc.html
107//! [`spawn`]: fn.spawn.html
108//! [`JoinHandle`]: struct.JoinHandle.html
109//! [`JoinHandle::task`]: struct.JoinHandle.html#method.task
110//! [`join`]: struct.JoinHandle.html#method.join
111//! [`panic!`]: https://doc.rust-lang.org/std/macro.panic.html
112//! [`Builder`]: struct.Builder.html
113//! [`Builder::name`]: struct.Builder.html#method.name
114//! [`task::current`]: fn.current.html
115//! [`Task`]: struct.Task.html
116//! [`Task::name`]: struct.Task.html#method.name
117//! [`task_local!`]: ../macro.task_local.html
118//! [`with`]: struct.LocalKey.html#method.with
119
120cfg_alloc! {
121    #[doc(inline)]
122    pub use core::task::{Context, Poll, Waker};
123    pub use ready::ready;
124
125    mod ready;
126}
127
128cfg_std! {
129    pub use yield_now::yield_now;
130    mod yield_now;
131}
132
133cfg_default! {
134    pub use block_on::block_on;
135    pub use builder::Builder;
136    pub use current::{current, try_current};
137    pub use task::Task;
138    pub use task_id::TaskId;
139    pub use join_handle::JoinHandle;
140    pub use sleep::sleep;
141    #[cfg(not(target_os = "unknown"))]
142    pub use spawn::spawn;
143    pub use task_local::{AccessError, LocalKey};
144
145    pub(crate) use task_local::LocalsMap;
146    pub(crate) use task_locals_wrapper::TaskLocalsWrapper;
147
148    mod block_on;
149    mod builder;
150    mod current;
151    mod join_handle;
152    mod sleep;
153    #[cfg(not(target_os = "unknown"))]
154    mod spawn;
155    #[cfg(not(target_os = "unknown"))]
156    mod spawn_blocking;
157    mod task;
158    mod task_id;
159    mod task_local;
160    mod task_locals_wrapper;
161
162    #[cfg(not(target_os = "unknown"))]
163    pub use spawn_blocking::spawn_blocking;
164}
165
166cfg_unstable! {
167    #[cfg(feature = "default")]
168    pub use spawn_local::spawn_local;
169
170    #[cfg(feature = "default")]
171    mod spawn_local;
172}