Skip to content

Adds data race in docs #32815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions src/doc/book/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ The same [ownership system](ownership.html) that helps prevent using pointers
incorrectly also helps rule out data races, one of the worst kinds of
concurrency bugs.

As an example, here is a Rust program that could have a data race in many
As an example, here is a Rust program that would have a data race in many
languages. It will not compile:

```ignore
Expand All @@ -174,7 +174,7 @@ fn main() {

for i in 0..3 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i isn't being used we should try for _ in 1..3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i is used (it's set to data[0]).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, missed that

thread::spawn(move || {
data[i] += 1;
data[0] += i;
});
}

Expand All @@ -186,7 +186,7 @@ This gives us an error:

```text
8:17 error: capture of moved value: `data`
data[i] += 1;
data[0] += i;
^~~~
```

Expand All @@ -195,11 +195,6 @@ thread, and the thread takes ownership of the reference, we'd have three owners!
`data` gets moved out of `main` in the first call to `spawn()`, so subsequent
calls in the loop cannot use this variable.

Note that this specific example will not cause a data race since different array
indices are being accessed. But this can't be determined at compile time, and in
a similar situation where `i` is a constant or is random, you would have a data
race.

So, we need some type that lets us have more than one owning reference to a
value. Usually, we'd use `Rc<T>` for this, which is a reference counted type
that provides shared ownership. It has some runtime bookkeeping that keeps track
Expand All @@ -223,7 +218,7 @@ fn main() {

// use it in a thread
thread::spawn(move || {
data_ref[i] += 1;
data_ref[0] += i;
});
}

Expand Down Expand Up @@ -266,7 +261,7 @@ fn main() {
for i in 0..3 {
let data = data.clone();
thread::spawn(move || {
data[i] += 1;
data[0] += i;
});
}

Expand All @@ -281,7 +276,7 @@ And... still gives us an error.

```text
<anon>:11:24 error: cannot borrow immutable borrowed content as mutable
<anon>:11 data[i] += 1;
<anon>:11 data[0] += i;
^~~~
```

Expand Down Expand Up @@ -317,7 +312,7 @@ fn main() {
let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data[i] += 1;
data[0] += i;
});
}

Expand Down Expand Up @@ -360,7 +355,7 @@ Let's examine the body of the thread more closely:
# let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data[i] += 1;
data[0] += i;
});
# }
# thread::sleep(Duration::from_millis(50));
Expand Down