about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJessy Diamond Exum <jessy.diamondman@gmail.com>2015-02-13 12:13:28 -0800
committerJessy Diamond Exum <jessy.diamondman@gmail.com>2015-02-22 11:45:31 -0800
commit6154c88ddcbe7ffacbf72a9acf508a377bbb96a7 (patch)
treed83047489c04ad5c21141d1dcc5226d4c7e2f414
parentdcc6ce2c772cb851ac35cbc2ddafcae9bf2fa9fd (diff)
downloadrust-6154c88ddcbe7ffacbf72a9acf508a377bbb96a7.tar.gz
rust-6154c88ddcbe7ffacbf72a9acf508a377bbb96a7.zip
Update intro.md to fix thread spawning example Closes #22419
Fixed example threaded code in intro doc never printing results. Threads were created with Thread::spawn instead of Thread::scoped.
-rw-r--r--src/doc/intro.md64
1 files changed, 30 insertions, 34 deletions
diff --git a/src/doc/intro.md b/src/doc/intro.md
index d9bfe71e2e4..c9d834ee123 100644
--- a/src/doc/intro.md
+++ b/src/doc/intro.md
@@ -426,39 +426,33 @@ use std::thread::Thread;
 fn main() {
     let mut numbers = vec![1, 2, 3];
 
-    for i in 0..3 {
-        Thread::spawn(move || {
+    let guards: Vec<_> = (0..3).map(|i| {
+        Thread::scoped(move || {
             for j in 0..3 { numbers[j] += 1 }
         });
-    }
+    }).collect();
 }
 ```
 
 It gives us this error:
 
 ```text
-6:71 error: capture of moved value: `numbers`
-    for j in 0..3 { numbers[j] += 1 }
-                    ^~~~~~~
-7:50 note: `numbers` moved into closure environment here
-    spawn(move || {
-        for j in 0..3 { numbers[j] += 1 }
-    });
-6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)
-        for j in 0..3 { numbers[j] += 1 }
-                        ^~~~~~~~~~~~~~~
+7:29: 9:10 error: cannot move out of captured outer variable in an `FnMut` closure
+7         Thread::scoped(move || {
+8             for j in 0..3 { numbers[j] += 1 }
+9         });
 ```
 
-It mentions that "numbers moved into closure environment". Because we
-declared the closure as a moving closure, and it referred to
-`numbers`, the closure will try to take ownership of the vector. But
-the closure itself is created in a loop, and hence we will actually
-create three closures, one for every iteration of the loop. This means
-that all three of those closures would try to own `numbers`, which is
-impossible -- `numbers` must have just one owner. Rust detects this
-and gives us the error: we claim that `numbers` has ownership, but our
-code tries to make three owners. This may cause a safety problem, so
-Rust disallows it.
+It mentions that "captured outer variable in an `FnMut` closure".
+Because we declared the closure as a moving closure, and it referred
+to `numbers`, the closure will try to take ownership of the
+vector. But the closure itself is created in a loop, and hence we will
+actually create three closures, one for every iteration of the
+loop. This means that all three of those closures would try to own
+`numbers`, which is impossible -- `numbers` must have just one
+owner. Rust detects this and gives us the error: we claim that
+`numbers` has ownership, but our code tries to make three owners. This
+may cause a safety problem, so Rust disallows it.
 
 What to do here? Rust has two types that helps us: `Arc<T>` and `Mutex<T>`.
 *Arc* stands for "atomically reference counted". In other words, an Arc will
@@ -480,14 +474,14 @@ use std::sync::{Arc,Mutex};
 fn main() {
     let numbers = Arc::new(Mutex::new(vec![1, 2, 3]));
 
-    for i in 0..3 {
+    let guards: Vec<_> = (0..3).map(|i| {
         let number = numbers.clone();
-        Thread::spawn(move || {
+        Thread::scoped(move || {
             let mut array = number.lock().unwrap();
             array[i] += 1;
             println!("numbers[{}] is {}", i, array[i]);
         });
-    }
+    }).collect();
 }
 ```
 
@@ -516,8 +510,10 @@ numbers[1] is 3
 numbers[0] is 2
 ```
 
-Each time, we get a slightly different output, because each thread works in a
-different order. You may not get the same output as this sample, even.
+Each time, we can get a slithtly different output because the threads
+are not quaranteed to run in any set order. If you get the same order
+every time it is because each of these threads are very small and
+complete too fast for their indeterminate behavior to surface.
 
 The important part here is that the Rust compiler was able to use ownership to
 give us assurance _at compile time_ that we weren't doing something incorrect
@@ -539,13 +535,13 @@ safety check that makes this an error about moved values:
 use std::thread::Thread;
 
 fn main() {
-    let vec = vec![1, 2, 3];
-
-    for i in 0..3 {
-        Thread::spawn(move || {
-            println!("{}", vec[i]);
+    let numbers = vec![1, 2, 3];
+    
+    let guards: Vec<_> = (0..3).map(|i| {
+        Thread::scoped(move || {
+            println!("{}", numbers[i]);
         });
-    }
+    }).collect();
 }
 ```