diff --git a/src/doc/book/concurrency.md b/src/doc/book/concurrency.md index ba4496b93f3..c179629a79a 100644 --- a/src/doc/book/concurrency.md +++ b/src/doc/book/concurrency.md @@ -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 @@ -174,7 +174,7 @@ fn main() { for i in 0..3 { thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -186,7 +186,7 @@ This gives us an error: ```text 8:17 error: capture of moved value: `data` - data[i] += 1; + data[0] += i; ^~~~ ``` @@ -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` for this, which is a reference counted type that provides shared ownership. It has some runtime bookkeeping that keeps track @@ -223,7 +218,7 @@ fn main() { // use it in a thread thread::spawn(move || { - data_ref[i] += 1; + data_ref[0] += i; }); } @@ -266,7 +261,7 @@ fn main() { for i in 0..3 { let data = data.clone(); thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -281,7 +276,7 @@ And... still gives us an error. ```text :11:24 error: cannot borrow immutable borrowed content as mutable -:11 data[i] += 1; +:11 data[0] += i; ^~~~ ``` @@ -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; }); } @@ -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));