Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread docs #38433

Merged
merged 1 commit into from
Dec 19, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 38 additions & 24 deletions src/libstd/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
//! provide some built-in support for low-level synchronization.
//!
//! Communication between threads can be done through
//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
//! types, along with [other forms of thread
//! [channels], Rust's message-passing types, along with [other forms of thread
//! synchronization](../../std/sync/index.html) and shared-memory data
//! structures. In particular, types that are guaranteed to be
//! threadsafe are easily shared between threads using the
//! atomically-reference-counted container,
//! [`Arc`](../../std/sync/struct.Arc.html).
//! atomically-reference-counted container, [`Arc`].
//!
//! Fatal logic errors in Rust cause *thread panic*, during which
//! a thread will unwind the stack, running destructors and freeing
Expand All @@ -40,7 +38,7 @@
//!
//! ## Spawning a thread
//!
//! A new thread can be spawned using the `thread::spawn` function:
//! A new thread can be spawned using the [`thread::spawn`][`spawn`] function:
//!
//! ```rust
//! use std::thread;
Expand All @@ -55,7 +53,7 @@
//! it), unless this parent is the main thread.
//!
//! The parent thread can also wait on the completion of the child
//! thread; a call to `spawn` produces a `JoinHandle`, which provides
//! thread; a call to [`spawn`] produces a [`JoinHandle`], which provides
//! a `join` method for waiting:
//!
//! ```rust
Expand All @@ -68,13 +66,13 @@
//! let res = child.join();
//! ```
//!
//! The `join` method returns a `Result` containing `Ok` of the final
//! value produced by the child thread, or `Err` of the value given to
//! a call to `panic!` if the child panicked.
//! The [`join`] method returns a [`Result`] containing [`Ok`] of the final
//! value produced by the child thread, or [`Err`] of the value given to
//! a call to [`panic!`] if the child panicked.
//!
//! ## Configuring threads
//!
//! A new thread can be configured before it is spawned via the `Builder` type,
//! A new thread can be configured before it is spawned via the [`Builder`] type,
//! which currently allows you to set the name and stack size for the child thread:
//!
//! ```rust
Expand All @@ -88,43 +86,43 @@
//!
//! ## The `Thread` type
//!
//! Threads are represented via the `Thread` type, which you can get in one of
//! Threads are represented via the [`Thread`] type, which you can get in one of
//! two ways:
//!
//! * By spawning a new thread, e.g. using the `thread::spawn` function, and
//! calling `thread()` on the `JoinHandle`.
//! * By requesting the current thread, using the `thread::current` function.
//! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
//! function, and calling [`thread()`] on the [`JoinHandle`].
//! * By requesting the current thread, using the [`thread::current()`] function.
//!
//! The `thread::current()` function is available even for threads not spawned
//! The [`thread::current()`] function is available even for threads not spawned
//! by the APIs of this module.
//!
//! ## Blocking support: park and unpark
//!
//! Every thread is equipped with some basic low-level blocking support, via the
//! `thread::park()` function and `thread::Thread::unpark()` method. `park()`
//! blocks the current thread, which can then be resumed from another thread by
//! calling the `unpark()` method on the blocked thread's handle.
//! [`thread::park()`][`park()`] function and [`thread::Thread::unpark()`][`unpark()`]
//! method. [`park()`] blocks the current thread, which can then be resumed from
//! another thread by calling the [`unpark()`] method on the blocked thread's handle.
//!
//! Conceptually, each `Thread` handle has an associated token, which is
//! Conceptually, each [`Thread`] handle has an associated token, which is
//! initially not present:
//!
//! * The `thread::park()` function blocks the current thread unless or until
//! * The [`thread::park()`][`park()`] function blocks the current thread unless or until
//! the token is available for its thread handle, at which point it atomically
//! consumes the token. It may also return *spuriously*, without consuming the
//! token. `thread::park_timeout()` does the same, but allows specifying a
//! token. [`thread::park_timeout()`] does the same, but allows specifying a
//! maximum time to block the thread for.
//!
//! * The `unpark()` method on a `Thread` atomically makes the token available
//! * The [`unpark()`] method on a [`Thread`] atomically makes the token available
//! if it wasn't already.
//!
//! In other words, each `Thread` acts a bit like a semaphore with initial count
//! In other words, each [`Thread`] acts a bit like a semaphore with initial count
//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
//! and can return spuriously.
//!
//! The API is typically used by acquiring a handle to the current thread,
//! placing that handle in a shared data structure so that other threads can
//! find it, and then `park`ing. When some desired condition is met, another
//! thread calls `unpark` on the handle.
//! thread calls [`unpark()`] on the handle.
//!
//! The motivation for this design is twofold:
//!
Expand All @@ -149,6 +147,22 @@
//! will want to make use of some form of **interior mutability** through the
//! [`Cell`] or [`RefCell`] types.
//!
//! [channels]: ../../std/sync/mpsc/index.html
//! [`Arc`]: ../../std/sync/struct.Arc.html
//! [`spawn`]: ../../std/thread/fn.spawn.html
//! [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
//! [`thread()`]: ../../std/thread/struct.JoinHandle.html#method.thread
//! [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
//! [`Result`]: ../../std/result/enum.Result.html
//! [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
//! [`Err`]: ../../std/result/enum.Result.html#variant.Err
//! [`panic!`]: ../../std/macro.panic.html
//! [`Builder`]: ../../std/thread/struct.Builder.html
//! [`thread::current()`]: ../../std/thread/fn.spawn.html
//! [`Thread`]: ../../std/thread/struct.Thread.html
//! [`park()`]: ../../std/thread/fn.park.html
//! [`unpark()`]: ../../std/thread/struct.Thread.html#method.unpark
//! [`thread::park_timeout()`]: ../../std/thread/fn.park_timeout.html
//! [`Cell`]: ../cell/struct.Cell.html
//! [`RefCell`]: ../cell/struct.RefCell.html
//! [`thread_local!`]: ../macro.thread_local.html
Expand Down