12
12
13
13
//! Threadsafe reference-counted boxes (the `Arc<T>` type).
14
14
//!
15
- //! The `Arc<T>` type provides shared ownership of an immutable value.
16
- //! Destruction is deterministic, and will occur as soon as the last owner is
17
- //! gone. It is marked as `Send` because it uses atomic reference counting.
18
- //!
19
- //! If you do not need thread-safety, and just need shared ownership, consider
20
- //! the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but
21
- //! does not use atomics, making it both thread-unsafe as well as significantly
22
- //! faster when updating the reference count.
23
- //!
24
- //! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer
25
- //! to the box. A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but
26
- //! will return `None` if the value has already been dropped.
27
- //!
28
- //! For example, a tree with parent pointers can be represented by putting the
29
- //! nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
30
- //! as `Weak<T>` pointers.
15
+ //! The `Arc<T>` type provides shared ownership of an immutable value through
16
+ //! atomic reference counting.
31
17
//!
18
+ //! `Weak<T>` is a weak reference to the `Arc<T>` box, and it is created by
19
+ //! the `downgrade` method.
32
20
//! # Examples
33
21
//!
34
22
//! Sharing some immutable data between threads:
47
35
//! });
48
36
//! }
49
37
//! ```
50
- //!
51
- //! Sharing mutable data safely between threads with a `Mutex`:
52
- //!
53
- //! ```no_run
54
- //! use std::sync::{Arc, Mutex};
55
- //! use std::thread;
56
- //!
57
- //! let five = Arc::new(Mutex::new(5));
58
- //!
59
- //! for _ in 0..10 {
60
- //! let five = five.clone();
61
- //!
62
- //! thread::spawn(move || {
63
- //! let mut number = five.lock().unwrap();
64
- //!
65
- //! *number += 1;
66
- //!
67
- //! println!("{}", *number); // prints 6
68
- //! });
69
- //! }
70
- //! ```
71
38
72
39
use boxed:: Box ;
73
40
@@ -92,15 +59,19 @@ use heap::deallocate;
92
59
const MAX_REFCOUNT : usize = ( isize:: MAX ) as usize ;
93
60
94
61
/// An atomically reference counted wrapper for shared state.
62
+ /// Destruction is deterministic, and will occur as soon as the last owner is
63
+ /// gone. It is marked as `Send` because it uses atomic reference counting.
95
64
///
96
- /// # Examples
65
+ /// If you do not need thread-safety, and just need shared ownership, consider
66
+ /// the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but
67
+ /// does not use atomics, making it both thread-unsafe as well as significantly
68
+ /// faster when updating the reference count.
97
69
///
98
- /// In this example, a large vector is shared between several threads.
99
- /// With simple pipes, without `Arc`, a copy would have to be made for each
100
- /// thread.
70
+ /// # Examples
101
71
///
102
- /// When you clone an `Arc<T>`, it will create another pointer to the data and
103
- /// increase the reference counter.
72
+ /// In this example, a large vector of data will be shared by several threads. First we
73
+ /// wrap it with a `Arc::new` and then clone the `Arc<T>` reference for every thread (which will
74
+ /// increase the reference count atomically).
104
75
///
105
76
/// ```
106
77
/// use std::sync::Arc;
@@ -111,6 +82,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
111
82
/// let shared_numbers = Arc::new(numbers);
112
83
///
113
84
/// for _ in 0..10 {
85
+ /// // prepare a copy of reference here and it will be moved to the thread
114
86
/// let child_numbers = shared_numbers.clone();
115
87
///
116
88
/// thread::spawn(move || {
@@ -121,6 +93,29 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
121
93
/// }
122
94
/// }
123
95
/// ```
96
+ /// You can also share mutable data between threads safely
97
+ /// by putting it inside `Mutex` and then share `Mutex` immutably
98
+ /// with `Arc<T>` as shown below.
99
+ ///
100
+ /// ```
101
+ /// use std::sync::{Arc, Mutex};
102
+ /// use std::thread;
103
+ ///
104
+ /// let five = Arc::new(Mutex::new(5));
105
+ ///
106
+ /// for _ in 0..10 {
107
+ /// let five = five.clone();
108
+ ///
109
+ /// thread::spawn(move || {
110
+ /// let mut number = five.lock().unwrap();
111
+ ///
112
+ /// *number += 1;
113
+ ///
114
+ /// println!("{}", *number); // prints 6
115
+ /// });
116
+ /// }
117
+ /// ```
118
+
124
119
#[ unsafe_no_drop_flag]
125
120
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
126
121
pub struct Arc < T : ?Sized > {
@@ -139,6 +134,14 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
139
134
///
140
135
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
141
136
/// used to break cycles between `Arc` pointers.
137
+ ///
138
+ /// A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but
139
+ /// will return `None` if the value has already been dropped.
140
+ ///
141
+ /// For example, a tree with parent pointers can be represented by putting the
142
+ /// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
143
+ /// as `Weak<T>` pointers.
144
+
142
145
#[ unsafe_no_drop_flag]
143
146
#[ stable( feature = "arc_weak" , since = "1.4.0" ) ]
144
147
pub struct Weak < T : ?Sized > {
0 commit comments