You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: branches/try/src/doc/trpl/concurrency.md
+61-33Lines changed: 61 additions & 33 deletions
Original file line number
Diff line number
Diff line change
@@ -135,28 +135,34 @@ This gives us an error:
135
135
^~~~
136
136
```
137
137
138
-
In this case, we know that our code _should_ be safe, but Rust isn't sure. And
139
-
it's actually not safe: if we had a reference to `data` in each thread, and the
140
-
thread takes ownership of the reference, we have three owners! That's bad. We
141
-
can fix this by using the `Arc<T>` type, which is an atomic reference counted
142
-
pointer. The 'atomic' part means that it's safe to share across threads.
138
+
Rust knows this wouldn't be safe! If we had a reference to `data` in each
139
+
thread, and the thread takes ownership of the reference, we'd have three
140
+
owners!
141
+
142
+
So, we need some type that lets us have more than one reference to a value and
143
+
that we can share between threads, that is it must implement `Sync`.
144
+
145
+
We'll use `Arc<T>`, rust's standard atomic reference count type, which
146
+
wraps a value up with some extra runtime bookkeeping which allows us to
147
+
share the ownership of the value between multiple references at the same time.
148
+
149
+
The bookkeeping consists of a count of how many of these references exist to
150
+
the value, hence the reference count part of the name.
151
+
152
+
The Atomic part means `Arc<T>` can safely be accessed from multiple threads.
153
+
To do this the compiler guarantees that mutations of the internal count use
154
+
indivisible operations which can't have data races.
143
155
144
-
`Arc<T>` assumes one more property about its contents to ensure that it is safe
145
-
to share across threads: it assumes its contents are `Sync`. But in our
146
-
case, we want to be able to mutate the value. We need a type that can ensure
147
-
only one person at a time can mutate what's inside. For that, we can use the
148
-
`Mutex<T>` type. Here's the second version of our code. It still doesn't work,
149
-
but for a different reason:
150
156
151
157
```ignore
152
158
use std::thread;
153
-
use std::sync::Mutex;
159
+
use std::sync::Arc;
154
160
155
161
fn main() {
156
-
let mut data = Mutex::new(vec![1, 2, 3]);
162
+
let mut data = Arc::new(vec![1, 2, 3]);
157
163
158
164
for i in 0..3 {
159
-
let data = data.lock().unwrap();
165
+
let data = data.clone();
160
166
thread::spawn(move || {
161
167
data[i] += 1;
162
168
});
@@ -166,29 +172,29 @@ fn main() {
166
172
}
167
173
```
168
174
169
-
Here's the error:
175
+
We now call `clone()` on our `Arc<T>`, which increases the internal count.
176
+
This handle is then moved into the new thread.
177
+
178
+
And... still gives us an error.
170
179
171
180
```text
172
-
<anon>:9:9: 9:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
173
-
<anon>:11 thread::spawn(move || {
174
-
^~~~~~~~~~~~~
175
-
<anon>:9:9: 9:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
176
-
<anon>:11 thread::spawn(move || {
177
-
^~~~~~~~~~~~~
181
+
<anon>:11:24 error: cannot borrow immutable borrowed content as mutable
182
+
<anon>:11 data[i] += 1;
183
+
^~~~
178
184
```
179
185
180
-
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
0 commit comments