Skip to main content

std/thread/
mod.rs

1//! Native threads.
2//!
3//! ## The threading model
4//!
5//! An executing Rust program consists of a collection of native OS threads,
6//! each with their own stack and local state. Threads can be named, and
7//! provide some built-in support for low-level synchronization.
8//!
9//! Communication between threads can be done through
10//! [channels], Rust's message-passing types, along with [other forms of thread
11//! synchronization](../../std/sync/index.html) and shared-memory data
12//! structures. In particular, types that are guaranteed to be
13//! threadsafe are easily shared between threads using the
14//! atomically-reference-counted container, [`Arc`].
15//!
16//! Fatal logic errors in Rust cause *thread panic*, during which
17//! a thread will unwind the stack, running destructors and freeing
18//! owned resources. While not meant as a 'try/catch' mechanism, panics
19//! in Rust can nonetheless be caught (unless compiling with `panic=abort`) with
20//! [`catch_unwind`](../../std/panic/fn.catch_unwind.html) and recovered
21//! from, or alternatively be resumed with
22//! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic
23//! is not caught the thread will exit, but the panic may optionally be
24//! detected from a different thread with [`join`]. If the main thread panics
25//! without the panic being caught, the application will exit with a
26//! non-zero exit code.
27//!
28//! When the main thread of a Rust program terminates, the entire program shuts
29//! down, even if other threads are still running, and any destructors on the
30//! remaining threads' stacks may not be executed.  However, this module
31//! provides convenient facilities for automatically waiting for the
32//! termination of a thread (i.e., join).
33//!
34//! ## Spawning a thread
35//!
36//! A new thread can be spawned using the [`thread::spawn`][`spawn`] function:
37//!
38//! ```rust
39//! use std::thread;
40//!
41//! thread::spawn(move || {
42//!     // some work here
43//! });
44//! ```
45//!
46//! In this example, the spawned thread is "detached," which means that there is
47//! no way for the program to learn when the spawned thread completes or otherwise
48//! terminates.
49//!
50//! To learn when a thread completes, it is necessary to capture the [`JoinHandle`]
51//! object that is returned by the call to [`spawn`], which provides
52//! a `join` method that allows the caller to wait for the completion of the
53//! spawned thread:
54//!
55//! ```rust
56//! use std::thread;
57//!
58//! let thread_join_handle = thread::spawn(move || {
59//!     // some work here
60//! });
61//! // some work here
62//! let res = thread_join_handle.join();
63//! ```
64//!
65//! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
66//! value produced by the spawned thread, or [`Err`] of the value given to
67//! a call to [`panic!`] if the thread panicked.
68//!
69//! Note that there is no parent/child relationship between a thread that spawns a
70//! new thread and the thread being spawned.  In particular, the spawned thread may or
71//! may not outlive the spawning thread, unless the spawning thread is the main thread.
72//!
73//! ## Configuring threads
74//!
75//! A new thread can be configured before it is spawned via the [`Builder`] type,
76//! which currently allows you to set the name and stack size for the thread:
77//!
78//! ```rust
79//! # #![allow(unused_must_use)]
80//! use std::thread;
81//!
82//! thread::Builder::new().name("thread1".to_string()).spawn(move || {
83//!     println!("Hello, world!");
84//! });
85//! ```
86//!
87//! ## The `Thread` type
88//!
89//! Threads are represented via the [`Thread`] type, which you can get in one of
90//! two ways:
91//!
92//! * By spawning a new thread, e.g., using the [`thread::spawn`][`spawn`]
93//!   function, and calling [`thread`][`JoinHandle::thread`] on the [`JoinHandle`].
94//! * By requesting the current thread, using the [`thread::current`] function.
95//!
96//! The [`thread::current`] function is available even for threads not spawned
97//! by the APIs of this module.
98//!
99//! ## Thread-local storage
100//!
101//! This module also provides an implementation of thread-local storage for Rust
102//! programs. Thread-local storage is a method of storing data into a global
103//! variable that each thread in the program will have its own copy of.
104//! Threads do not share this data, so accesses do not need to be synchronized.
105//!
106//! A thread-local key owns the value it contains and will destroy the value when the
107//! thread exits. It is created with the [`thread_local!`] macro and can contain any
108//! value that is `'static` (no borrowed pointers). It provides an accessor function,
109//! [`with`], that yields a shared reference to the value to the specified
110//! closure. Thread-local keys allow only shared access to values, as there would be no
111//! way to guarantee uniqueness if mutable borrows were allowed. Most values
112//! will want to make use of some form of **interior mutability** through the
113//! [`Cell`] or [`RefCell`] types.
114//!
115//! ## Naming threads
116//!
117//! Threads are able to have associated names for identification purposes. By default, spawned
118//! threads are unnamed. To specify a name for a thread, build the thread with [`Builder`] and pass
119//! the desired thread name to [`Builder::name`]. To retrieve the thread name from within the
120//! thread, use [`Thread::name`]. A couple of examples where the name of a thread gets used:
121//!
122//! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
123//! * The thread name is provided to the OS where applicable (e.g., `pthread_setname_np` in
124//!   unix-like platforms).
125//!
126//! ## Stack size
127//!
128//! The default stack size is platform-dependent and subject to change.
129//! Currently, it is 2 MiB on all Tier-1 platforms.
130//!
131//! There are two ways to manually specify the stack size for spawned threads:
132//!
133//! * Build the thread with [`Builder`] and pass the desired stack size to [`Builder::stack_size`].
134//! * Set the `RUST_MIN_STACK` environment variable to an integer representing the desired stack
135//!   size (in bytes). Note that setting [`Builder::stack_size`] will override this. Be aware that
136//!   changes to `RUST_MIN_STACK` may be ignored after program start.
137//!
138//! Note that the stack size of the main thread is *not* determined by Rust.
139//!
140//! [channels]: crate::sync::mpsc
141//! [`Arc`]: crate::sync::Arc
142//! [`join`]: JoinHandle::join
143//! [`Result`]: crate::result::Result
144//! [`Ok`]: crate::result::Result::Ok
145//! [`Err`]: crate::result::Result::Err
146//! [`thread::current`]: current::current
147//! [`thread::Result`]: Result
148//! [`unpark`]: Thread::unpark
149//! [`thread::park_timeout`]: park_timeout
150//! [`Cell`]: crate::cell::Cell
151//! [`RefCell`]: crate::cell::RefCell
152//! [`with`]: LocalKey::with
153//! [`thread_local!`]: crate::thread_local
154
155#![stable(feature = "rust1", since = "1.0.0")]
156#![deny(unsafe_op_in_unsafe_fn)]
157// Under `test`, `__FastLocalKeyInner` seems unused.
158#![cfg_attr(test, allow(dead_code))]
159
160use crate::any::Any;
161
162#[macro_use]
163mod local;
164mod builder;
165mod current;
166mod functions;
167mod id;
168mod join_handle;
169mod lifecycle;
170mod scoped;
171mod spawnhook;
172mod thread;
173
174pub(crate) mod main_thread;
175
176#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
177mod tests;
178
179#[stable(feature = "rust1", since = "1.0.0")]
180pub use builder::Builder;
181#[stable(feature = "rust1", since = "1.0.0")]
182pub use current::current;
183#[unstable(feature = "current_thread_id", issue = "147194")]
184pub use current::current_id;
185pub(crate) use current::{current_or_unnamed, current_os_id, drop_current, with_current_name};
186#[stable(feature = "available_parallelism", since = "1.59.0")]
187pub use functions::available_parallelism;
188#[stable(feature = "park_timeout", since = "1.4.0")]
189pub use functions::park_timeout;
190#[stable(feature = "thread_sleep", since = "1.4.0")]
191pub use functions::sleep;
192#[unstable(feature = "thread_sleep_until", issue = "113752")]
193pub use functions::sleep_until;
194#[expect(deprecated)]
195#[stable(feature = "rust1", since = "1.0.0")]
196pub use functions::{panicking, park, park_timeout_ms, sleep_ms, spawn, yield_now};
197#[stable(feature = "thread_id", since = "1.19.0")]
198pub use id::ThreadId;
199#[stable(feature = "rust1", since = "1.0.0")]
200pub use join_handle::JoinHandle;
201pub(crate) use lifecycle::ThreadInit;
202#[stable(feature = "rust1", since = "1.0.0")]
203pub use local::{AccessError, LocalKey};
204#[stable(feature = "scoped_threads", since = "1.63.0")]
205pub use scoped::{Scope, ScopedJoinHandle, scope};
206#[unstable(feature = "thread_spawn_hook", issue = "132951")]
207pub use spawnhook::add_spawn_hook;
208#[stable(feature = "rust1", since = "1.0.0")]
209pub use thread::Thread;
210
211// Implementation details used by the thread_local!{} macro.
212#[doc(hidden)]
213#[unstable(feature = "thread_local_internals", issue = "none")]
214pub mod local_impl {
215    pub use super::local::thread_local_process_attrs;
216    pub use crate::sys::thread_local::*;
217}
218
219/// A specialized [`Result`] type for threads.
220///
221/// Indicates the manner in which a thread exited.
222///
223/// The value contained in the `Result::Err` variant
224/// is the value the thread panicked with;
225/// that is, the argument the `panic!` macro was called with.
226/// Unlike with normal errors, this value doesn't implement
227/// the [`Error`](crate::error::Error) trait.
228///
229/// Thus, a sensible way to handle a thread panic is to either:
230///
231/// 1. propagate the panic with [`std::panic::resume_unwind`]
232/// 2. or in case the thread is intended to be a subsystem boundary
233/// that is supposed to isolate system-level failures,
234/// match on the `Err` variant and handle the panic in an appropriate way
235///
236/// A thread that completes without panicking is considered to exit successfully.
237///
238/// # Examples
239///
240/// Matching on the result of a joined thread:
241///
242/// ```no_run
243/// use std::{fs, thread, panic};
244///
245/// fn copy_in_thread() -> thread::Result<()> {
246///     thread::spawn(|| {
247///         fs::copy("foo.txt", "bar.txt").unwrap();
248///     }).join()
249/// }
250///
251/// fn main() {
252///     match copy_in_thread() {
253///         Ok(_) => println!("copy succeeded"),
254///         Err(e) => panic::resume_unwind(e),
255///     }
256/// }
257/// ```
258///
259/// [`Result`]: crate::result::Result
260/// [`std::panic::resume_unwind`]: crate::panic::resume_unwind
261#[stable(feature = "rust1", since = "1.0.0")]
262#[doc(search_unbox)]
263pub type Result<T> = crate::result::Result<T, Box<dyn Any + Send + 'static>>;
264
265fn _assert_sync_and_send() {
266    fn _assert_both<T: Send + Sync>() {}
267    _assert_both::<JoinHandle<()>>();
268    _assert_both::<Thread>();
269}