From a6ff05cd8387efbb0286e9e35d11111c3b6380fe Mon Sep 17 00:00:00 2001 From: Zhen Zhang Date: Sat, 9 Jul 2016 11:47:36 +0800 Subject: [PATCH] Improve arc doc, fixing #32905 --- src/liballoc/arc.rs | 89 +++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 729d9218a29..e762e4d8ce9 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -12,23 +12,11 @@ //! Threadsafe reference-counted boxes (the `Arc` type). //! -//! The `Arc` type provides shared ownership of an immutable value. -//! Destruction is deterministic, and will occur as soon as the last owner is -//! gone. It is marked as `Send` because it uses atomic reference counting. -//! -//! If you do not need thread-safety, and just need shared ownership, consider -//! the [`Rc` type](../rc/struct.Rc.html). It is the same as `Arc`, but -//! does not use atomics, making it both thread-unsafe as well as significantly -//! faster when updating the reference count. -//! -//! The `downgrade` method can be used to create a non-owning `Weak` pointer -//! to the box. A `Weak` pointer can be upgraded to an `Arc` pointer, but -//! will return `None` if the value has already been dropped. -//! -//! For example, a tree with parent pointers can be represented by putting the -//! nodes behind strong `Arc` pointers, and then storing the parent pointers -//! as `Weak` pointers. +//! The `Arc` type provides shared ownership of an immutable value through +//! atomic reference counting. //! +//! `Weak` is a weak reference to the `Arc` box, and it is created by +//! the `downgrade` method. //! # Examples //! //! Sharing some immutable data between threads: @@ -47,27 +35,6 @@ //! }); //! } //! ``` -//! -//! Sharing mutable data safely between threads with a `Mutex`: -//! -//! ```no_run -//! use std::sync::{Arc, Mutex}; -//! use std::thread; -//! -//! let five = Arc::new(Mutex::new(5)); -//! -//! for _ in 0..10 { -//! let five = five.clone(); -//! -//! thread::spawn(move || { -//! let mut number = five.lock().unwrap(); -//! -//! *number += 1; -//! -//! println!("{}", *number); // prints 6 -//! }); -//! } -//! ``` use boxed::Box; @@ -92,15 +59,19 @@ use heap::deallocate; const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// An atomically reference counted wrapper for shared state. +/// Destruction is deterministic, and will occur as soon as the last owner is +/// gone. It is marked as `Send` because it uses atomic reference counting. +/// +/// If you do not need thread-safety, and just need shared ownership, consider +/// the [`Rc` type](../rc/struct.Rc.html). It is the same as `Arc`, but +/// does not use atomics, making it both thread-unsafe as well as significantly +/// faster when updating the reference count. /// /// # Examples /// -/// In this example, a large vector is shared between several threads. -/// With simple pipes, without `Arc`, a copy would have to be made for each -/// thread. -/// -/// When you clone an `Arc`, it will create another pointer to the data and -/// increase the reference counter. +/// In this example, a large vector of data will be shared by several threads. First we +/// wrap it with a `Arc::new` and then clone the `Arc` reference for every thread (which will +/// increase the reference count atomically). /// /// ``` /// use std::sync::Arc; @@ -111,6 +82,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// let shared_numbers = Arc::new(numbers); /// /// for _ in 0..10 { +/// // prepare a copy of reference here and it will be moved to the thread /// let child_numbers = shared_numbers.clone(); /// /// thread::spawn(move || { @@ -121,6 +93,29 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// } /// } /// ``` +/// You can also share mutable data between threads safely +/// by putting it inside `Mutex` and then share `Mutex` immutably +/// with `Arc` as shown below. +/// +/// ``` +/// use std::sync::{Arc, Mutex}; +/// use std::thread; +/// +/// let five = Arc::new(Mutex::new(5)); +/// +/// for _ in 0..10 { +/// let five = five.clone(); +/// +/// thread::spawn(move || { +/// let mut number = five.lock().unwrap(); +/// +/// *number += 1; +/// +/// println!("{}", *number); // prints 6 +/// }); +/// } +/// ``` + #[unsafe_no_drop_flag] #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc { @@ -139,6 +134,14 @@ impl, U: ?Sized> CoerceUnsized> for Arc {} /// /// Weak pointers will not keep the data inside of the `Arc` alive, and can be /// used to break cycles between `Arc` pointers. +/// +/// A `Weak` pointer can be upgraded to an `Arc` pointer, but +/// will return `None` if the value has already been dropped. +/// +/// For example, a tree with parent pointers can be represented by putting the +/// nodes behind strong `Arc` pointers, and then storing the parent pointers +/// as `Weak` pointers. + #[unsafe_no_drop_flag] #[stable(feature = "arc_weak", since = "1.4.0")] pub struct Weak {