@@ -457,30 +457,25 @@ a problem. That’s what it means by ‘cannot move out of captured outer
457
457
variable’: our ` thread::scoped` closure wants to take ownership, and it can’t,
458
458
because the closure for ` map` won’t let it.
459
459
460
- What to do here? Rust has two types that helps us: ` Arc< T> ` and ` Mutex< T> ` .
461
- * Arc* stands for " atomically reference counted" . In other words, an Arc will
462
- keep track of the number of references to something, and not free the
463
- associated resource until the count is zero. The * atomic* portion refers to an
464
- Arc' s usage of concurrency primitives to atomically update the count, making it
465
- safe across threads. If we use an Arc, we can have our three references. But,
466
- an Arc does not allow mutable borrows of the data it holds, and we want to
467
- modify what we' re sharing. In this case, we can use a ` Mutex< T> ` inside of our
468
- Arc. A Mutex will synchronize our accesses, so that we can ensure that our
469
- mutation doesn' t cause a data race.
470
-
471
- Here' s what using an Arc with a Mutex looks like:
460
+ What to do here? Rust has a type that helps us: ` Mutex< T> ` . Because the threads
461
+ are scoped, it is possible to use an _immutable_ reference to ` numbers` inside
462
+ of the closure. However, Rust prevents us from having multiple _mutable_
463
+ references to the same object, so we need a ` Mutex` to be able to modify what
464
+ we' re sharing. A Mutex will synchronize our accesses, so that we can ensure
465
+ that our mutation doesn' t cause a data race.
466
+
467
+ Here' s what using a Mutex looks like:
472
468
473
469
```{rust}
474
470
use std::thread;
475
- use std::sync::{Arc, Mutex} ;
471
+ use std::sync::Mutex;
476
472
477
473
fn main() {
478
- let numbers = Arc::new( Mutex::new(vec! [1, 2, 3]) );
474
+ let numbers = & Mutex::new(vec![1, 2, 3]);
479
475
480
476
let guards: Vec<_> = (0..3).map(|i| {
481
- let number = numbers.clone ();
482
477
thread::scoped(move || {
483
- let mut array = number .lock().unwrap ();
478
+ let mut array = numbers .lock().unwrap();
484
479
array[i] += 1;
485
480
println!("numbers[{}] is {}", i, array[i]);
486
481
})
@@ -489,12 +484,9 @@ fn main() {
489
484
```
490
485
491
486
We first have to `use` the appropriate library, and then we wrap our vector in
492
- an Arc with the call to `Arc::new ()` . Inside of the loop, we make a new
493
- reference to the Arc with the ` clone()` method. This will increment the
494
- reference count. When each new ` numbers` variable binding goes out of scope, it
495
- will decrement the count. The ` lock()` call will return us a reference to the
496
- value inside the Mutex, and block any other calls to ` lock()` until said
497
- reference goes out of scope.
487
+ a `Mutex` with the call to `Mutex::new()`. Inside of the loop, the `lock()`
488
+ call will return us a reference to the value inside the Mutex, and block any
489
+ other calls to `lock()` until said reference goes out of scope.
498
490
499
491
We can compile and run this program without error, and in fact, see the
500
492
non-deterministic aspect:
0 commit comments