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