Skip to content

Commit

Permalink
Rollup merge of rust-lang#32815 - allonsy:master, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Adds data race in docs

Thanks for all your hard work!
This is in reference to rust-lang#32733
I know there has been a discussion about this on PR rust-lang#32538 so you are welcome to keep the code as is or merge my documentation in.
Let me know what you think and/or if you want me to modify anything!
  • Loading branch information
steveklabnik committed Apr 11, 2016
2 parents 47cc036 + 4d8fac0 commit b5fc27c
Showing 1 changed file with 8 additions and 13 deletions.
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 {
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

0 comments on commit b5fc27c

Please sign in to comment.