Skip to content

Commit 64d9ae2

Browse files
committed
---
yaml --- r: 229199 b: refs/heads/try c: c1f938d h: refs/heads/master i: 229197: aeabca1 229195: 80fc1f3 229191: 06b8c49 229183: 80eba7c v: v3
1 parent 279ae57 commit 64d9ae2

File tree

177 files changed

+673
-1081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+673
-1081
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 76ff835ca0b6669b185e6a4aeedc144432db91f8
4+
refs/heads/try: c1f938d7b834852aede4f865a18ee2226668a8e6
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/mk/main.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
######################################################################
1414

1515
# The version number
16-
CFG_RELEASE_NUM=1.4.0
16+
CFG_RELEASE_NUM=1.3.0
1717

1818
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
1919
# NB Make sure it starts with a dot to conform to semver pre-release

branches/try/src/doc/trpl/concurrency.md

Lines changed: 38 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ languages. It will not compile:
115115
use std::thread;
116116
117117
fn main() {
118-
let mut data = vec![1, 2, 3];
118+
let mut data = vec![1u32, 2, 3];
119119
120120
for i in 0..3 {
121121
thread::spawn(move || {
@@ -135,34 +135,28 @@ This gives us an error:
135135
^~~~
136136
```
137137

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.
155143

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:
156150

157151
```ignore
158152
use std::thread;
159-
use std::sync::Arc;
153+
use std::sync::Mutex;
160154
161155
fn main() {
162-
let mut data = Arc::new(vec![1, 2, 3]);
156+
let mut data = Mutex::new(vec![1u32, 2, 3]);
163157
164158
for i in 0..3 {
165-
let data = data.clone();
159+
let data = data.lock().unwrap();
166160
thread::spawn(move || {
167161
data[i] += 1;
168162
});
@@ -172,36 +166,36 @@ fn main() {
172166
}
173167
```
174168

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:
179170

180171
```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+
^~~~~~~~~~~~~
184178
```
185179

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
181+
[`lock`](../std/sync/struct.Mutex.html#method.lock)
182+
method which has this signature:
190183

191-
It looks like we need some type that allows us to safely mutate a shared value,
192-
for example a type that that can ensure only one thread at a time is able to
193-
mutate the value inside it at any one time.
184+
```ignore
185+
fn lock(&self) -> LockResult<MutexGuard<T>>
186+
```
194187

195-
For that, we can use the `Mutex<T>` type!
188+
Because `Send` is not implemented for `MutexGuard<T>`, we can't transfer the
189+
guard across thread boundaries, which gives us our error.
196190

197-
Here's the working version:
191+
We can use `Arc<T>` to fix this. Here's the working version:
198192

199193
```rust
200194
use std::sync::{Arc, Mutex};
201195
use std::thread;
202196

203197
fn main() {
204-
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
198+
let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
205199

206200
for i in 0..3 {
207201
let data = data.clone();
@@ -215,37 +209,15 @@ fn main() {
215209
}
216210
```
217211

218-
219-
If we'd tried to use `Mutex<T>` without wrapping it in an `Arc<T>` we would have
220-
seen another error like:
221-
222-
```text
223-
error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
224-
thread::spawn(move || {
225-
^~~~~~~~~~~~~
226-
note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
227-
thread::spawn(move || {
228-
^~~~~~~~~~~~~
229-
```
230-
231-
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
232-
[`lock`](../std/sync/struct.Mutex.html#method.lock)
233-
method which has this signature:
234-
235-
```ignore
236-
fn lock(&self) -> LockResult<MutexGuard<T>>
237-
```
238-
239-
and because `Send` is not implemented for `MutexGuard<T>`, we couldn't have
240-
transferred the guard across thread boundaries on it's own.
241-
242-
Let's examine the body of the thread more closely:
212+
We now call `clone()` on our `Arc`, which increases the internal count. This
213+
handle is then moved into the new thread. Let's examine the body of the
214+
thread more closely:
243215

244216
```rust
245217
# use std::sync::{Arc, Mutex};
246218
# use std::thread;
247219
# fn main() {
248-
# let data = Arc::new(Mutex::new(vec![1, 2, 3]));
220+
# let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
249221
# for i in 0..3 {
250222
# let data = data.clone();
251223
thread::spawn(move || {
@@ -283,7 +255,7 @@ use std::thread;
283255
use std::sync::mpsc;
284256

285257
fn main() {
286-
let data = Arc::new(Mutex::new(0));
258+
let data = Arc::new(Mutex::new(0u32));
287259

288260
let (tx, rx) = mpsc::channel();
289261

@@ -321,7 +293,7 @@ fn main() {
321293
let tx = tx.clone();
322294

323295
thread::spawn(move || {
324-
let answer = 42;
296+
let answer = 42u32;
325297

326298
tx.send(answer);
327299
});

0 commit comments

Comments
 (0)