mod.rs - source
Description: Source of the Rust file `library/std/src/thread/mod.rs`.

#
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}