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
+38-66Lines changed: 38 additions & 66 deletions
Original file line number
Diff line number
Diff line change
@@ -115,7 +115,7 @@ languages. It will not compile:
115
115
use std::thread;
116
116
117
117
fn main() {
118
-
let mut data = vec![1, 2, 3];
118
+
let mut data = vec![1u32, 2, 3];
119
119
120
120
for i in 0..3 {
121
121
thread::spawn(move || {
@@ -135,34 +135,28 @@ This gives us an error:
135
135
^~~~
136
136
```
137
137
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.
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.
155
143
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:
156
150
157
151
```ignore
158
152
use std::thread;
159
-
use std::sync::Arc;
153
+
use std::sync::Mutex;
160
154
161
155
fn main() {
162
-
let mut data = Arc::new(vec![1, 2, 3]);
156
+
let mut data = Mutex::new(vec![1u32, 2, 3]);
163
157
164
158
for i in 0..3 {
165
-
let data = data.clone();
159
+
let data = data.lock().unwrap();
166
160
thread::spawn(move || {
167
161
data[i] += 1;
168
162
});
@@ -172,36 +166,36 @@ fn main() {
172
166
}
173
167
```
174
168
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.
169
+
Here's the error:
179
170
180
171
```text
181
-
<anon>:11:24 error: cannot borrow immutable borrowed content as mutable
182
-
<anon>:11 data[i] += 1;
183
-
^~~~
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
+
^~~~~~~~~~~~~
184
178
```
185
179
186
-
`Arc<T>` assumes one more property about its contents to ensure that it is safe
187
-
to share across threads: it assumes its contents are `Sync`. This is true for
188
-
our value if it's immutable, but we want to be able to mutate it, so we need
189
-
something else to persuade the borrow checker we know what we're doing.
180
+
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
0 commit comments