The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Testing with Mock Objects

One important part of this code is that the `Messenger` trait has one method
called `send` that takes an immutable reference to `self` and the text of the
message. This trait is the interface our mock object needs to implement so that
the mock can be used in the same way a real object is. The other important part
is that we want to test the behavior of the `set_value` method on the
`LimitTracker`. We can change what we pass in for the `value` parameter, but
`set_value` doesn’t return anything for us to make assertions on. We want to be
able to say that if we create a `LimitTracker` with something that implements
the `Messenger` trait and a particular value for `max`, the messenger is told
to send the appropriate messages when we pass different numbers for `value`.
We need a mock object that, instead of sending an email or text message when we
call `send`, will only keep track of the messages it’s told to send. We can
create a new instance of the mock object, create a `LimitTracker` that uses the
mock object, call the `set_value` method on `LimitTracker`, and then check that
the mock object has the messages we expect. Listing 15-21 shows an attempt to
implement a mock object to do just that, but the borrow checker won’t allow it.
Listing 15-21: An attempt to implement a `MockMessenger` that isn’t allowed by the borrow checker (src/lib.rs)


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Testing with Mock Objects

```rust,ignore,does_not_compile
#[cfg(test)]
mod tests {
    use super::*;

    struct MockMessenger {
        sent_messages: Vec<String>,
    }

    impl MockMessenger {
        fn new() -> MockMessenger {
            MockMessenger {
                sent_messages: vec![],
            }
        }
    }

    impl Messenger for MockMessenger {
        fn send(&self, message: &str) {
            self.sent_messages.push(String::from(message));
        }
    }

    #[test]
    fn it_sends_an_over_75_percent_warning_message() {
        let mock_messenger = MockMessenger::new();
        let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);

        limit_tracker.set_value(80);

        assert_eq!(mock_messenger.sent_messages.len(), 1);
    }
}
```
This test code defines a `MockMessenger` struct that has a `sent_messages`
field with a `Vec` of `String` values to keep track of the messages it’s told
to send. We also define an associated function `new` to make it convenient to
create new `MockMessenger` values that start with an empty list of messages. We
then implement the `Messenger` trait for `MockMessenger` so that we can give a
`MockMessenger` to a `LimitTracker`. In the definition of the `send` method, we
take the message passed in as a parameter and store it in the `MockMessenger`
list of `sent_messages`.


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Testing with Mock Objects

In the test, we’re testing what happens when the `LimitTracker` is told to set
`value` to something that is more than 75 percent of the `max` value. First, we
create a new `MockMessenger`, which will start with an empty list of messages.
Then, we create a new `LimitTracker` and give it a reference to the new
`MockMessenger` and a `max` value of `100`. We call the `set_value` method on
the `LimitTracker` with a value of `80`, which is more than 75 percent of 100.
Then, we assert that the list of messages that the `MockMessenger` is keeping
track of should now have one message in it.
However, there’s one problem with this test, as shown here:
```console
$ cargo test
   Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)
error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference
  --> src/lib.rs:58:13
   |
58 |             self.sent_messages.push(String::from(message));
   |             ^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable
   |
help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition
   |
 2 ~     fn send(&mut self, msg: &str);
 3 | }
...
56 |     impl Messenger for MockMessenger {
57 ~         fn send(&mut self, message: &str) {
   |

For more information about this error, try `rustc --explain E0596`.
error: could not compile `limit-tracker` (lib test) due to 1 previous error
```


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Testing with Mock Objects

We can’t modify the `MockMessenger` to keep track of the messages, because the
`send` method takes an immutable reference to `self`. We also can’t take the
suggestion from the error text to use `&mut self` in both the `impl` method and
the trait definition. We do not want to change the `Messenger` trait solely for
the sake of testing. Instead, we need to find a way to make our test code work
correctly with our existing design.
This is a situation in which interior mutability can help! We’ll store the
`sent_messages` within a `RefCell<T>`, and then the `send` method will be able
to modify `sent_messages` to store the messages we’ve seen. Listing 15-22 shows
what that looks like.
Listing 15-22 (src/lib.rs)
```rust,noplayground
#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::RefCell;

    struct MockMessenger {
        sent_messages: RefCell<Vec<String>>,
    }

    impl MockMessenger {
        fn new() -> MockMessenger {
            MockMessenger {
                sent_messages: RefCell::new(vec![]),
            }
        }
    }

    impl Messenger for MockMessenger {
        fn send(&self, message: &str) {
            self.sent_messages.borrow_mut().push(String::from(message));
        }
    }

    #[test]
    fn it_sends_an_over_75_percent_warning_message() {
        // --snip--

        assert_eq!(mock_messenger.sent_messages.borrow().len(), 1);
    }
}
```
The `sent_messages` field is now of type `RefCell<Vec<String>>` instead of
`Vec<String>`. In the `new` function, we create a new `RefCell<Vec<String>>`
instance around the empty vector.


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Tracking Borrows at Runtime

For the implementation of the `send` method, the first parameter is still an
immutable borrow of `self`, which matches the trait definition. We call
`borrow_mut` on the `RefCell<Vec<String>>` in `self.sent_messages` to get a
mutable reference to the value inside the `RefCell<Vec<String>>`, which is the
vector. Then, we can call `push` on the mutable reference to the vector to keep
track of the messages sent during the test.
The last change we have to make is in the assertion: To see how many items are
in the inner vector, we call `borrow` on the `RefCell<Vec<String>>` to get an
immutable reference to the vector.
Now that you’ve seen how to use `RefCell<T>`, let’s dig into how it works!
When creating immutable and mutable references, we use the `&` and `&mut`
syntax, respectively. With `RefCell<T>`, we use the `borrow` and `borrow_mut`
methods, which are part of the safe API that belongs to `RefCell<T>`. The
`borrow` method returns the smart pointer type `Ref<T>`, and `borrow_mut`
returns the smart pointer type `RefMut<T>`. Both types implement `Deref`, so we
can treat them like regular references.
The `RefCell<T>` keeps track of how many `Ref<T>` and `RefMut<T>` smart
pointers are currently active. Every time we call `borrow`, the `RefCell<T>`
increases its count of how many immutable borrows are active. When a `Ref<T>`
value goes out of scope, the count of immutable borrows goes down by 1. Just
like the compile-time borrowing rules, `RefCell<T>` lets us have many immutable
borrows or one mutable borrow at any point in time.


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Tracking Borrows at Runtime

If we try to violate these rules, rather than getting a compiler error as we
would with references, the implementation of `RefCell<T>` will panic at
runtime. Listing 15-23 shows a modification of the implementation of `send` in
Listing 15-22. We’re deliberately trying to create two mutable borrows active
for the same scope to illustrate that `RefCell<T>` prevents us from doing this
at runtime.
Listing 15-23 (src/lib.rs)
```rust,ignore,panics
    impl Messenger for MockMessenger {
        fn send(&self, message: &str) {
            let mut one_borrow = self.sent_messages.borrow_mut();
            let mut two_borrow = self.sent_messages.borrow_mut();

            one_borrow.push(String::from(message));
            two_borrow.push(String::from(message));
        }
    }
```
We create a variable `one_borrow` for the `RefMut<T>` smart pointer returned
from `borrow_mut`. Then, we create another mutable borrow in the same way in
the variable `two_borrow`. This makes two mutable references in the same scope,
which isn’t allowed. When we run the tests for our library, the code in Listing
15-23 will compile without any errors, but the test will fail:


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Tracking Borrows at Runtime

```console
$ cargo test
   Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.91s
     Running unittests src/lib.rs (target/debug/deps/limit_tracker-e599811fa246dbde)

running 1 test
test tests::it_sends_an_over_75_percent_warning_message ... FAILED

failures:

---- tests::it_sends_an_over_75_percent_warning_message stdout ----

thread 'tests::it_sends_an_over_75_percent_warning_message' (6028024) panicked at src/lib.rs:60:53:
RefCell already borrowed
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

failures:
    tests::it_sends_an_over_75_percent_warning_message

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--lib`
```
Notice that the code panicked with the message `already borrowed:
BorrowMutError`. This is how `RefCell<T>` handles violations of the borrowing
rules at runtime.


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Using Interior Mutability › Tracking Borrows at Runtime

Choosing to catch borrowing errors at runtime rather than compile time, as
we’ve done here, means you’d potentially be finding mistakes in your code later
in the development process: possibly not until your code was deployed to
production. Also, your code would incur a small runtime performance penalty as
a result of keeping track of the borrows at runtime rather than compile time.
However, using `RefCell<T>` makes it possible to write a mock object that can
modify itself to keep track of the messages it has seen while you’re using it
in a context where only immutable values are allowed. You can use `RefCell<T>`
despite its trade-offs to get more functionality than regular references
provide.


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Allowing Multiple Owners of Mutable Data

A common way to use `RefCell<T>` is in combination with `Rc<T>`. Recall that
`Rc<T>` lets you have multiple owners of some data, but it only gives immutable
access to that data. If you have an `Rc<T>` that holds a `RefCell<T>`, you can
get a value that can have multiple owners _and_ that you can mutate!
For example, recall the cons list example in Listing 15-18 where we used
`Rc<T>` to allow multiple lists to share ownership of another list. Because
`Rc<T>` holds only immutable values, we can’t change any of the values in the
list once we’ve created them. Let’s add in `RefCell<T>` for its ability to
change the values in the lists. Listing 15-24 shows that by using a
`RefCell<T>` in the `Cons` definition, we can modify the value stored in all
the lists.
Listing 15-24 (src/main.rs)
```rust
#[derive(Debug)]
enum List {
    Cons(Rc<RefCell<i32>>, Rc<List>),
    Nil,
}

use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;

fn main() {
    let value = Rc::new(RefCell::new(5));

    let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));

    let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
    let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));

    *value.borrow_mut() += 10;

    println!("a after = {a:?}");
    println!("b after = {b:?}");
    println!("c after = {c:?}");
}
```


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Allowing Multiple Owners of Mutable Data

We create a value that is an instance of `Rc<RefCell<i32>>` and store it in a
variable named `value` so that we can access it directly later. Then, we create
a `List` in `a` with a `Cons` variant that holds `value`. We need to clone
`value` so that both `a` and `value` have ownership of the inner `5` value
rather than transferring ownership from `value` to `a` or having `a` borrow
from `value`.
We wrap the list `a` in an `Rc<T>` so that when we create lists `b` and `c`,
they can both refer to `a`, which is what we did in Listing 15-18.
After we’ve created the lists in `a`, `b`, and `c`, we want to add 10 to the
value in `value`. We do this by calling `borrow_mut` on `value`, which uses the
automatic dereferencing feature we discussed in “Where’s the `->`
Operator?” in Chapter 5 to dereference
the `Rc<T>` to the inner `RefCell<T>` value. The `borrow_mut` method returns a
`RefMut<T>` smart pointer, and we use the dereference operator on it and change
the inner value.
When we print `a`, `b`, and `c`, we can see that they all have the modified
value of `15` rather than `5`:


The Rust Programming Language › `RefCell<T>` and the Interior Mutability Pattern › Allowing Multiple Owners of Mutable Data

```console
$ cargo run
   Compiling cons-list v0.1.0 (file:///projects/cons-list)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.63s
     Running `target/debug/cons-list`
a after = Cons(RefCell { value: 15 }, Nil)
b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil))
c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil))
```
This technique is pretty neat! By using `RefCell<T>`, we have an outwardly
immutable `List` value. But we can use the methods on `RefCell<T>` that provide
access to its interior mutability so that we can modify our data when we need
to. The runtime checks of the borrowing rules protect us from data races, and
it’s sometimes worth trading a bit of speed for this flexibility in our data
structures. Note that `RefCell<T>` does not work for multithreaded code!
`Mutex<T>` is the thread-safe version of `RefCell<T>`, and we’ll discuss
`Mutex<T>` in Chapter 16.


The Rust Programming Language › Reference Cycles Can Leak Memory

Rust’s memory safety guarantees make it difficult, but not impossible, to
accidentally create memory that is never cleaned up (known as a _memory leak_).
Preventing memory leaks entirely is not one of Rust’s guarantees, meaning
memory leaks are memory safe in Rust. We can see that Rust allows memory leaks
by using `Rc<T>` and `RefCell<T>`: It’s possible to create references where
items refer to each other in a cycle. This creates memory leaks because the
reference count of each item in the cycle will never reach 0, and the values
will never be dropped.


The Rust Programming Language › Reference Cycles Can Leak Memory › Creating a Reference Cycle

Let’s look at how a reference cycle might happen and how to prevent it,
starting with the definition of the `List` enum and a `tail` method in Listing
15-25.
Listing 15-25 (src/main.rs)
```rust
use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug)]
enum List {
    Cons(i32, RefCell<Rc<List>>),
    Nil,
}

impl List {
    fn tail(&self) -> Option<&RefCell<Rc<List>>> {
        match self {
            Cons(_, item) => Some(item),
            Nil => None,
        }
    }
}
```
We’re using another variation of the `List` definition from Listing 15-5. The
second element in the `Cons` variant is now `RefCell<Rc<List>>`, meaning that
instead of having the ability to modify the `i32` value as we did in Listing
15-24, we want to modify the `List` value a `Cons` variant is pointing to.
We’re also adding a `tail` method to make it convenient for us to access the
second item if we have a `Cons` variant.
In Listing 15-26, we’re adding a `main` function that uses the definitions in
Listing 15-25. This code creates a list in `a` and a list in `b` that points to
the list in `a`. Then, it modifies the list in `a` to point to `b`, creating a
reference cycle. There are `println!` statements along the way to show what the
reference counts are at various points in this process.
Listing 15-26: Creating a reference cycle of two `List` values pointing to each other (src/main.rs)

Reference Cycles Can Leak Memory
Creating a Reference Cycle


The Rust Programming Language › Reference Cycles Can Leak Memory › Creating a Reference Cycle

```rust
fn main() {
    let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));

    println!("a initial rc count = {}", Rc::strong_count(&a));
    println!("a next item = {:?}", a.tail());

    let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));

    println!("a rc count after b creation = {}", Rc::strong_count(&a));
    println!("b initial rc count = {}", Rc::strong_count(&b));
    println!("b next item = {:?}", b.tail());

    if let Some(link) = a.tail() {
        *link.borrow_mut() = Rc::clone(&b);
    }

    println!("b rc count after changing a = {}", Rc::strong_count(&b));
    println!("a rc count after changing a = {}", Rc::strong_count(&a));

    // Uncomment the next line to see that we have a cycle;
    // it will overflow the stack.
    // println!("a next item = {:?}", a.tail());
}
```
We create an `Rc<List>` instance holding a `List` value in the variable `a`
with an initial list of `5, Nil`. We then create an `Rc<List>` instance holding
another `List` value in the variable `b` that contains the value `10` and
points to the list in `a`.


The Rust Programming Language › Reference Cycles Can Leak Memory › Creating a Reference Cycle

We modify `a` so that it points to `b` instead of `Nil`, creating a cycle. We
do that by using the `tail` method to get a reference to the
`RefCell<Rc<List>>` in `a`, which we put in the variable `link`. Then, we use
the `borrow_mut` method on the `RefCell<Rc<List>>` to change the value inside
from an `Rc<List>` that holds a `Nil` value to the `Rc<List>` in `b`.
When we run this code, keeping the last `println!` commented out for the
moment, we’ll get this output:
```console
$ cargo run
   Compiling cons-list v0.1.0 (file:///projects/cons-list)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.53s
     Running `target/debug/cons-list`
a initial rc count = 1
a next item = Some(RefCell { value: Nil })
a rc count after b creation = 2
b initial rc count = 1
b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) })
b rc count after changing a = 2
a rc count after changing a = 2
```


The Rust Programming Language › Reference Cycles Can Leak Memory › Creating a Reference Cycle

The reference count of the `Rc<List>` instances in both `a` and `b` is 2 after
we change the list in `a` to point to `b`. At the end of `main`, Rust drops the
variable `b`, which decreases the reference count of the `b` `Rc<List>`
instance from 2 to 1. The memory that `Rc<List>` has on the heap won’t be
dropped at this point because its reference count is 1, not 0. Then, Rust drops
`a`, which decreases the reference count of the `a` `Rc<List>` instance from 2
to 1 as well. This instance’s memory can’t be dropped either, because the other
`Rc<List>` instance still refers to it. The memory allocated to the list will
remain uncollected forever. To visualize this reference cycle, we’ve created
the diagram in Figure 15-4.

Figure 15-4: A reference cycle of lists `a` and `b`
pointing to each other
If you uncomment the last `println!` and run the program, Rust will try to
print this cycle with `a` pointing to `b` pointing to `a` and so forth until it
overflows the stack.


The Rust Programming Language › Reference Cycles Can Leak Memory › Creating a Reference Cycle

Compared to a real-world program, the consequences of creating a reference
cycle in this example aren’t very dire: Right after we create the reference
cycle, the program ends. However, if a more complex program allocated lots of
memory in a cycle and held onto it for a long time, the program would use more
memory than it needed and might overwhelm the system, causing it to run out of
available memory.
Creating reference cycles is not easily done, but it’s not impossible either.
If you have `RefCell<T>` values that contain `Rc<T>` values or similar nested
combinations of types with interior mutability and reference counting, you must
ensure that you don’t create cycles; you can’t rely on Rust to catch them.
Creating a reference cycle would be a logic bug in your program that you should
use automated tests, code reviews, and other software development practices to
minimize.
Another solution for avoiding reference cycles is reorganizing your data
structures so that some references express ownership and some references don’t.
As a result, you can have cycles made up of some ownership relationships and
some non-ownership relationships, and only the ownership relationships affect
whether or not a value can be dropped. In Listing 15-25, we always want `Cons`
variants to own their list, so reorganizing the data structure isn’t possible.
Let’s look at an example using graphs made up of parent nodes and child nodes
to see when non-ownership relationships are an appropriate way to prevent
reference cycles.


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>`

So far, we’ve demonstrated that calling `Rc::clone` increases the
`strong_count` of an `Rc<T>` instance, and an `Rc<T>` instance is only cleaned
up if its `strong_count` is 0. You can also create a weak reference to the
value within an `Rc<T>` instance by calling `Rc::downgrade` and passing a
reference to the `Rc<T>`. *Strong references* are how you can share ownership
of an `Rc<T>` instance. *Weak references* don’t express an ownership
relationship, and their count doesn’t affect when an `Rc<T>` instance is
cleaned up. They won’t cause a reference cycle, because any cycle involving
some weak references will be broken once the strong reference count of values
involved is 0.
When you call `Rc::downgrade`, you get a smart pointer of type `Weak<T>`.
Instead of increasing the `strong_count` in the `Rc<T>` instance by 1, calling
`Rc::downgrade` increases the `weak_count` by 1. The `Rc<T>` type uses
`weak_count` to keep track of how many `Weak<T>` references exist, similar to
`strong_count`. The difference is the `weak_count` doesn’t need to be 0 for the
`Rc<T>` instance to be cleaned up.


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Creating a Tree Data Structure

Because the value that `Weak<T>` references might have been dropped, to do
anything with the value that a `Weak<T>` is pointing to you must make sure the
value still exists. Do this by calling the `upgrade` method on a `Weak<T>`
instance, which will return an `Option<Rc<T>>`. You’ll get a result of `Some`
if the `Rc<T>` value has not been dropped yet and a result of `None` if the
`Rc<T>` value has been dropped. Because `upgrade` returns an `Option<Rc<T>>`,
Rust will ensure that the `Some` case and the `None` case are handled, and
there won’t be an invalid pointer.
As an example, rather than using a list whose items know only about the next
item, we’ll create a tree whose items know about their child items _and_ their
parent items.
To start, we’ll build a tree with nodes that know about their child nodes.
We’ll create a struct named `Node` that holds its own `i32` value as well as
references to its child `Node` values:
Filename: src/main.rs
```rust
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug)]
struct Node {
    value: i32,
    children: RefCell<Vec<Rc<Node>>>,
}
```
We want a `Node` to own its children, and we want to share that ownership with
variables so that we can access each `Node` in the tree directly. To do this,
we define the `Vec<T>` items to be values of type `Rc<Node>`. We also want to
modify which nodes are children of another node, so we have a `RefCell<T>` in
`children` around the `Vec<Rc<Node>>`.


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Adding a Reference from a Child to Its Parent

Next, we’ll use our struct definition and create one `Node` instance named
`leaf` with the value `3` and no children, and another instance named `branch`
with the value `5` and `leaf` as one of its children, as shown in Listing 15-27.
Listing 15-27: Creating a `leaf` node with no children and a `branch` node with `leaf` as one of its children (src/main.rs)
```rust
fn main() {
    let leaf = Rc::new(Node {
        value: 3,
        children: RefCell::new(vec![]),
    });

    let branch = Rc::new(Node {
        value: 5,
        children: RefCell::new(vec![Rc::clone(&leaf)]),
    });
}
```
We clone the `Rc<Node>` in `leaf` and store that in `branch`, meaning the
`Node` in `leaf` now has two owners: `leaf` and `branch`. We can get from
`branch` to `leaf` through `branch.children`, but there’s no way to get from
`leaf` to `branch`. The reason is that `leaf` has no reference to `branch` and
doesn’t know they’re related. We want `leaf` to know that `branch` is its
parent. We’ll do that next.
To make the child node aware of its parent, we need to add a `parent` field to
our `Node` struct definition. The trouble is in deciding what the type of
`parent` should be. We know it can’t contain an `Rc<T>`, because that would
create a reference cycle with `leaf.parent` pointing to `branch` and
`branch.children` pointing to `leaf`, which would cause their `strong_count`
values to never be 0.


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Adding a Reference from a Child to Its Parent

Thinking about the relationships another way, a parent node should own its
children: If a parent node is dropped, its child nodes should be dropped as
well. However, a child should not own its parent: If we drop a child node, the
parent should still exist. This is a case for weak references!
So, instead of `Rc<T>`, we’ll make the type of `parent` use `Weak<T>`,
specifically a `RefCell<Weak<Node>>`. Now our `Node` struct definition looks
like this:
Filename: src/main.rs
```rust
use std::cell::RefCell;
use std::rc::{Rc, Weak};

#[derive(Debug)]
struct Node {
    value: i32,
    parent: RefCell<Weak<Node>>,
    children: RefCell<Vec<Rc<Node>>>,
}
```
A node will be able to refer to its parent node but doesn’t own its parent. In
Listing 15-28, we update `main` to use this new definition so that the `leaf`
node will have a way to refer to its parent, `branch`.
Listing 15-28: A `leaf` node with a weak reference to its parent node, `branch` (src/main.rs)
```rust
fn main() {
    let leaf = Rc::new(Node {
        value: 3,
        parent: RefCell::new(Weak::new()),
        children: RefCell::new(vec![]),
    });

    println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());

    let branch = Rc::new(Node {
        value: 5,
        parent: RefCell::new(Weak::new()),
        children: RefCell::new(vec![Rc::clone(&leaf)]),
    });

    *leaf.parent.borrow_mut() = Rc::downgrade(&branch);

    println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
}
```


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Adding a Reference from a Child to Its Parent

Creating the `leaf` node looks similar to Listing 15-27 with the exception of
the `parent` field: `leaf` starts out without a parent, so we create a new,
empty `Weak<Node>` reference instance.
At this point, when we try to get a reference to the parent of `leaf` by using
the `upgrade` method, we get a `None` value. We see this in the output from the
first `println!` statement:
```text
leaf parent = None
```
When we create the `branch` node, it will also have a new `Weak<Node>`
reference in the `parent` field because `branch` doesn’t have a parent node. We
still have `leaf` as one of the children of `branch`. Once we have the `Node`
instance in `branch`, we can modify `leaf` to give it a `Weak<Node>` reference
to its parent. We use the `borrow_mut` method on the `RefCell<Weak<Node>>` in
the `parent` field of `leaf`, and then we use the `Rc::downgrade` function to
create a `Weak<Node>` reference to `branch` from the `Rc<Node>` in `branch`.
When we print the parent of `leaf` again, this time we’ll get a `Some` variant
holding `branch`: Now `leaf` can access its parent! When we print `leaf`, we
also avoid the cycle that eventually ended in a stack overflow like we had in
Listing 15-26; the `Weak<Node>` references are printed as `(Weak)`:
```text
leaf parent = Some(Node { value: 5, parent: RefCell { value: (Weak) },
children: RefCell { value: [Node { value: 3, parent: RefCell { value: (Weak) },
children: RefCell { value: [] } }] } })
```


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Visualizing Changes to `strong_count` and `weak_count`

The lack of infinite output indicates that this code didn’t create a reference
cycle. We can also tell this by looking at the values we get from calling
`Rc::strong_count` and `Rc::weak_count`.
Let’s look at how the `strong_count` and `weak_count` values of the `Rc<Node>`
instances change by creating a new inner scope and moving the creation of
`branch` into that scope. By doing so, we can see what happens when `branch` is
created and then dropped when it goes out of scope. The modifications are shown
in Listing 15-29.
Listing 15-29: Creating `branch` in an inner scope and examining strong and weak reference counts (src/main.rs)
```rust
fn main() {
    let leaf = Rc::new(Node {
        value: 3,
        parent: RefCell::new(Weak::new()),
        children: RefCell::new(vec![]),
    });

    println!(
        "leaf strong = {}, weak = {}",
        Rc::strong_count(&leaf),
        Rc::weak_count(&leaf),
    );

    {
        let branch = Rc::new(Node {
            value: 5,
            parent: RefCell::new(Weak::new()),
            children: RefCell::new(vec![Rc::clone(&leaf)]),
        });

        *leaf.parent.borrow_mut() = Rc::downgrade(&branch);

        println!(
            "branch strong = {}, weak = {}",
            Rc::strong_count(&branch),
            Rc::weak_count(&branch),
        );

        println!(
            "leaf strong = {}, weak = {}",
            Rc::strong_count(&leaf),
            Rc::weak_count(&leaf),
        );
    }

    println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
    println!(
        "leaf strong = {}, weak = {}",
        Rc::strong_count(&leaf),
        Rc::weak_count(&leaf),
    );
}
```


The Rust Programming Language › Reference Cycles Can Leak Memory › Preventing Reference Cycles Using `Weak<T>` › Visualizing Changes to `strong_count` and `weak_count`

After `leaf` is created, its `Rc<Node>` has a strong count of 1 and a weak
count of 0. In the inner scope, we create `branch` and associate it with
`leaf`, at which point when we print the counts, the `Rc<Node>` in `branch`
will have a strong count of 1 and a weak count of 1 (for `leaf.parent` pointing
to `branch` with a `Weak<Node>`). When we print the counts in `leaf`, we’ll see
it will have a strong count of 2 because `branch` now has a clone of the
`Rc<Node>` of `leaf` stored in `branch.children` but will still have a weak
count of 0.
When the inner scope ends, `branch` goes out of scope and the strong count of
the `Rc<Node>` decreases to 0, so its `Node` is dropped. The weak count of 1
from `leaf.parent` has no bearing on whether or not `Node` is dropped, so we
don’t get any memory leaks!
If we try to access the parent of `leaf` after the end of the scope, we’ll get
`None` again. At the end of the program, the `Rc<Node>` in `leaf` has a strong
count of 1 and a weak count of 0 because the variable `leaf` is now the only
reference to the `Rc<Node>` again.
All of the logic that manages the counts and value dropping is built into
`Rc<T>` and `Weak<T>` and their implementations of the `Drop` trait. By
specifying that the relationship from a child to its parent should be a
`Weak<T>` reference in the definition of `Node`, you’re able to have parent
nodes point to child nodes and vice versa without creating a reference cycle
and memory leaks.


The Rust Programming Language › Summary

This chapter covered how to use smart pointers to make different guarantees and
trade-offs from those Rust makes by default with regular references. The
`Box<T>` type has a known size and points to data allocated on the heap. The
`Rc<T>` type keeps track of the number of references to data on the heap so
that the data can have multiple owners. The `RefCell<T>` type with its interior
mutability gives us a type that we can use when we need an immutable type but
need to change an inner value of that type; it also enforces the borrowing
rules at runtime instead of at compile time.
Also discussed were the `Deref` and `Drop` traits, which enable a lot of the
functionality of smart pointers. We explored reference cycles that can cause
memory leaks and how to prevent them using `Weak<T>`.
If this chapter has piqued your interest and you want to implement your own
smart pointers, check out “The Rustonomicon” for more useful
information.
Next, we’ll talk about concurrency in Rust. You’ll even learn about a few new
smart pointers.


The Rust Programming Language › Fearless Concurrency

Handling concurrent programming safely and efficiently is another of Rust’s
major goals. _Concurrent programming_, in which different parts of a program
execute independently, and _parallel programming_, in which different parts of
a program execute at the same time, are becoming increasingly important as more
computers take advantage of their multiple processors. Historically,
programming in these contexts has been difficult and error-prone. Rust hopes to
change that.
Initially, the Rust team thought that ensuring memory safety and preventing
concurrency problems were two separate challenges to be solved with different
methods. Over time, the team discovered that the ownership and type systems are
a powerful set of tools to help manage memory safety _and_ concurrency
problems! By leveraging ownership and type checking, many concurrency errors
are compile-time errors in Rust rather than runtime errors. Therefore, rather
than making you spend lots of time trying to reproduce the exact circumstances
under which a runtime concurrency bug occurs, incorrect code will refuse to
compile and present an error explaining the problem. As a result, you can fix
your code while you’re working on it rather than potentially after it has been
shipped to production. We’ve nicknamed this aspect of Rust _fearless
concurrency_. Fearless concurrency allows you to write code that is free of
subtle bugs and is easy to refactor without introducing new bugs.
Note: For simplicity’s sake, we’ll refer to many of the problems as
_concurrent_ rather than being more precise by saying _concurrent and/or
parallel_. For this chapter, please mentally substitute _concurrent and/or
parallel_ whenever we use _concurrent_. In the next chapter, where the
distinction matters more, we’ll be more specific.


The Rust Programming Language › Fearless Concurrency

Many languages are dogmatic about the solutions they offer for handling
concurrent problems. For example, Erlang has elegant functionality for
message-passing concurrency but has only obscure ways to share state between
threads. Supporting only a subset of possible solutions is a reasonable
strategy for higher-level languages because a higher-level language promises
benefits from giving up some control to gain abstractions. However, lower-level
languages are expected to provide the solution with the best performance in any
given situation and have fewer abstractions over the hardware. Therefore, Rust
offers a variety of tools for modeling problems in whatever way is appropriate
for your situation and requirements.
Here are the topics we’ll cover in this chapter:
- How to create threads to run multiple pieces of code at the same time
- _Message-passing_ concurrency, where channels send messages between threads
- _Shared-state_ concurrency, where multiple threads have access to some piece
  of data
- The `Sync` and `Send` traits, which extend Rust’s concurrency guarantees to
  user-defined types as well as types provided by the standard library


The Rust Programming Language › Using Threads to Run Code Simultaneously

In most current operating systems, an executed program’s code is run in a
_process_, and the operating system will manage multiple processes at once.
Within a program, you can also have independent parts that run simultaneously.
The features that run these independent parts are called _threads_. For
example, a web server could have multiple threads so that it can respond to
more than one request at the same time.
Splitting the computation in your program into multiple threads to run multiple
tasks at the same time can improve performance, but it also adds complexity.
Because threads can run simultaneously, there’s no inherent guarantee about the
order in which parts of your code on different threads will run. This can lead
to problems, such as:
- Race conditions, in which threads are accessing data or resources in an
  inconsistent order
- Deadlocks, in which two threads are waiting for each other, preventing both
  threads from continuing
- Bugs that only happen in certain situations and are hard to reproduce and fix
  reliably
Rust attempts to mitigate the negative effects of using threads, but
programming in a multithreaded context still takes careful thought and requires
a code structure that is different from that in programs running in a single
thread.
Programming languages implement threads in a few different ways, and many
operating systems provide an API the programming language can call for creating
new threads. The Rust standard library uses a _1:1_ model of thread
implementation, whereby a program uses one operating system thread per one
language thread. There are crates that implement other models of threading that
make different trade-offs to the 1:1 model. (Rust’s async system, which we will
see in the next chapter, provides another approach to concurrency as well.)


The Rust Programming Language › Using Threads to Run Code Simultaneously › Creating a New Thread with `spawn`

To create a new thread, we call the `thread::spawn` function and pass it a
closure (we talked about closures in Chapter 13) containing the code we want to
run in the new thread. The example in Listing 16-1 prints some text from a main
thread and other text from a new thread.
Listing 16-1: Creating a new thread to print one thing while the main thread prints something else (src/main.rs)
```rust
use std::thread;
use std::time::Duration;

fn main() {
    thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {i} from the spawned thread!");
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi number {i} from the main thread!");
        thread::sleep(Duration::from_millis(1));
    }
}
```
Note that when the main thread of a Rust program completes, all spawned threads
are shut down, whether or not they have finished running. The output from this
program might be a little different every time, but it will look similar to the
following:
```text
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the main thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
```


The Rust Programming Language › Using Threads to Run Code Simultaneously › Creating a New Thread with `spawn`

The calls to `thread::sleep` force a thread to stop its execution for a short
duration, allowing a different thread to run. The threads will probably take
turns, but that isn’t guaranteed: It depends on how your operating system
schedules the threads. In this run, the main thread printed first, even though
the print statement from the spawned thread appears first in the code. And even
though we told the spawned thread to print until `i` is `9`, it only got to `5`
before the main thread shut down.
If you run this code and only see output from the main thread, or don’t see any
overlap, try increasing the numbers in the ranges to create more opportunities
for the operating system to switch between the threads.


The Rust Programming Language › Using Threads to Run Code Simultaneously › Waiting for All Threads to Finish

The code in Listing 16-1 not only stops the spawned thread prematurely most of
the time due to the main thread ending, but because there is no guarantee on
the order in which threads run, we also can’t guarantee that the spawned thread
will get to run at all!
We can fix the problem of the spawned thread not running or of it ending
prematurely by saving the return value of `thread::spawn` in a variable. The
return type of `thread::spawn` is `JoinHandle<T>`. A `JoinHandle<T>` is an
owned value that, when we call the `join` method on it, will wait for its
thread to finish. Listing 16-2 shows how to use the `JoinHandle<T>` of the
thread we created in Listing 16-1 and how to call `join` to make sure the
spawned thread finishes before `main` exits.
Listing 16-2 (src/main.rs)
```rust
use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {i} from the spawned thread!");
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi number {i} from the main thread!");
        thread::sleep(Duration::from_millis(1));
    }

    handle.join().unwrap();
}
```
Calling `join` on the handle blocks the thread currently running until the
thread represented by the handle terminates. _Blocking_ a thread means that
thread is prevented from performing work or exiting. Because we’ve put the call
to `join` after the main thread’s `for` loop, running Listing 16-2 should
produce output similar to this:


The Rust Programming Language › Using Threads to Run Code Simultaneously › Waiting for All Threads to Finish

```text
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 1 from the spawned thread!
hi number 3 from the main thread!
hi number 2 from the spawned thread!
hi number 4 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
```
The two threads continue alternating, but the main thread waits because of the
call to `handle.join()` and does not end until the spawned thread is finished.
But let’s see what happens when we instead move `handle.join()` before the
`for` loop in `main`, like this:
Listing (src/main.rs)
```rust
use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {i} from the spawned thread!");
            thread::sleep(Duration::from_millis(1));
        }
    });

    handle.join().unwrap();

    for i in 1..5 {
        println!("hi number {i} from the main thread!");
        thread::sleep(Duration::from_millis(1));
    }
}
```
The main thread will wait for the spawned thread to finish and then run its
`for` loop, so the output won’t be interleaved anymore, as shown here:


The Rust Programming Language › Using Threads to Run Code Simultaneously › Waiting for All Threads to Finish

```text
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
```
Small details, such as where `join` is called, can affect whether or not your
threads run at the same time.


The Rust Programming Language › Using Threads to Run Code Simultaneously › Using `move` Closures with Threads

We’ll often use the `move` keyword with closures passed to `thread::spawn`
because the closure will then take ownership of the values it uses from the
environment, thus transferring ownership of those values from one thread to
another. In “Capturing References or Moving Ownership”
 in Chapter 13, we discussed `move` in the context of closures. Now we’ll
concentrate more on the interaction between `move` and `thread::spawn`.
Notice in Listing 16-1 that the closure we pass to `thread::spawn` takes no
arguments: We’re not using any data from the main thread in the spawned
thread’s code. To use data from the main thread in the spawned thread, the
spawned thread’s closure must capture the values it needs. Listing 16-3 shows
an attempt to create a vector in the main thread and use it in the spawned
thread. However, this won’t work yet, as you’ll see in a moment.
Listing 16-3: Attempting to use a vector created by the main thread in another thread (src/main.rs)
```rust,ignore,does_not_compile
use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(|| {
        println!("Here's a vector: {v:?}");
    });

    handle.join().unwrap();
}
```
The closure uses `v`, so it will capture `v` and make it part of the closure’s
environment. Because `thread::spawn` runs this closure in a new thread, we
should be able to access `v` inside that new thread. But when we compile this
example, we get the following error:


The Rust Programming Language › Using Threads to Run Code Simultaneously › Using `move` Closures with Threads

```console
$ cargo run
   Compiling threads v0.1.0 (file:///projects/threads)
error[E0373]: closure may outlive the current function, but it borrows `v`, which is owned by the current function
 --> src/main.rs:6:32
  |
6 |     let handle = thread::spawn(|| {
  |                                ^^ may outlive borrowed value `v`
7 |         println!("Here's a vector: {v:?}");
  |                                     - `v` is borrowed here
  |
note: function requires argument type to outlive `'static`
 --> src/main.rs:6:18
  |
6 |       let handle = thread::spawn(|| {
  |  __________________^
7 | |         println!("Here's a vector: {v:?}");
8 | |     });
  | |______^
help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword
  |
6 |     let handle = thread::spawn(move || {
  |                                ++++

For more information about this error, try `rustc --explain E0373`.
error: could not compile `threads` (bin "threads") due to 1 previous error
```
Rust _infers_ how to capture `v`, and because `println!` only needs a reference
to `v`, the closure tries to borrow `v`. However, there’s a problem: Rust can’t
tell how long the spawned thread will run, so it doesn’t know whether the
reference to `v` will always be valid.
Listing 16-4 provides a scenario that’s more likely to have a reference to `v`
that won’t be valid.
Listing 16-4: A thread with a closure that attempts to capture a reference to `v` from a main thread that drops `v` (src/main.rs)


The Rust Programming Language › Using Threads to Run Code Simultaneously › Using `move` Closures with Threads

```rust,ignore,does_not_compile
use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(|| {
        println!("Here's a vector: {v:?}");
    });

    drop(v); // oh no!

    handle.join().unwrap();
}
```
If Rust allowed us to run this code, there’s a possibility that the spawned
thread would be immediately put in the background without running at all. The
spawned thread has a reference to `v` inside, but the main thread immediately
drops `v`, using the `drop` function we discussed in Chapter 15. Then, when the
spawned thread starts to execute, `v` is no longer valid, so a reference to it
is also invalid. Oh no!
To fix the compiler error in Listing 16-3, we can use the error message’s
advice:
```text
help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword
  |
6 |     let handle = thread::spawn(move || {
  |                                ++++
```
By adding the `move` keyword before the closure, we force the closure to take
ownership of the values it’s using rather than allowing Rust to infer that it
should borrow the values. The modification to Listing 16-3 shown in Listing
16-5 will compile and run as we intend.
Listing 16-5: Using the `move` keyword to force a closure to take ownership of the values it uses (src/main.rs)
```rust
use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("Here's a vector: {v:?}");
    });

    handle.join().unwrap();
}
```


The Rust Programming Language › Using Threads to Run Code Simultaneously › Using `move` Closures with Threads

We might be tempted to try the same thing to fix the code in Listing 16-4 where
the main thread called `drop` by using a `move` closure. However, this fix will
not work because what Listing 16-4 is trying to do is disallowed for a
different reason. If we added `move` to the closure, we would move `v` into the
closure’s environment, and we could no longer call `drop` on it in the main
thread. We would get this compiler error instead:
```console
$ cargo run
   Compiling threads v0.1.0 (file:///projects/threads)
error[E0382]: use of moved value: `v`
  --> src/main.rs:10:10
   |
 4 |     let v = vec![1, 2, 3];
   |         - move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
 5 |
 6 |     let handle = thread::spawn(move || {
   |                                ------- value moved into closure here
 7 |         println!("Here's a vector: {v:?}");
   |                                     - variable moved due to use in closure
...
10 |     drop(v); // oh no!
   |          ^ value used here after move
   |
help: consider cloning the value before moving it into the closure
   |
 6 ~     let value = v.clone();
 7 ~     let handle = thread::spawn(move || {
 8 ~         println!("Here's a vector: {value:?}");
   |

For more information about this error, try `rustc --explain E0382`.
error: could not compile `threads` (bin "threads") due to 1 previous error
```


The Rust Programming Language › Using Threads to Run Code Simultaneously › Using `move` Closures with Threads

Rust’s ownership rules have saved us again! We got an error from the code in
Listing 16-3 because Rust was being conservative and only borrowing `v` for the
thread, which meant the main thread could theoretically invalidate the spawned
thread’s reference. By telling Rust to move ownership of `v` to the spawned
thread, we’re guaranteeing to Rust that the main thread won’t use `v` anymore.
If we change Listing 16-4 in the same way, we’re then violating the ownership
rules when we try to use `v` in the main thread. The `move` keyword overrides
Rust’s conservative default of borrowing; it doesn’t let us violate the
ownership rules.
Now that we’ve covered what threads are and the methods supplied by the thread
API, let’s look at some situations in which we can use threads.


The Rust Programming Language › Transfer Data Between Threads with Message Passing

One increasingly popular approach to ensuring safe concurrency is message
passing, where threads or actors communicate by sending each other messages
containing data. Here’s the idea in a slogan from the Go language documentation:
“Do not communicate by sharing memory; instead, share memory by communicating.”
To accomplish message-sending concurrency, Rust’s standard library provides an
implementation of channels. A _channel_ is a general programming concept by
which data is sent from one thread to another.
You can imagine a channel in programming as being like a directional channel of
water, such as a stream or a river. If you put something like a rubber duck
into a river, it will travel downstream to the end of the waterway.
A channel has two halves: a transmitter and a receiver. The transmitter half is
the upstream location where you put the rubber duck into the river, and the
receiver half is where the rubber duck ends up downstream. One part of your
code calls methods on the transmitter with the data you want to send, and
another part checks the receiving end for arriving messages. A channel is said
to be _closed_ if either the transmitter or receiver half is dropped.
Here, we’ll work up to a program that has one thread to generate values and
send them down a channel, and another thread that will receive the values and
print them out. We’ll be sending simple values between threads using a channel
to illustrate the feature. Once you’re familiar with the technique, you could
use channels for any threads that need to communicate with each other, such as
a chat system or a system where many threads perform parts of a calculation and
send the parts to one thread that aggregates the results.
First, in Listing 16-6, we’ll create a channel but not do anything with it.
Note that this won’t compile yet because Rust can’t tell what type of values we
want to send over the channel.


The Rust Programming Language › Transfer Data Between Threads with Message Passing

Listing 16-6: Creating a channel and assigning the two halves to `tx` and `rx` (src/main.rs)
```rust,ignore,does_not_compile
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();
}
```
We create a new channel using the `mpsc::channel` function; `mpsc` stands for
_multiple producer, single consumer_. In short, the way Rust’s standard library
implements channels means a channel can have multiple _sending_ ends that
produce values but only one _receiving_ end that consumes those values. Imagine
multiple streams flowing together into one big river: Everything sent down any
of the streams will end up in one river at the end. We’ll start with a single
producer for now, but we’ll add multiple producers when we get this example
working.
The `mpsc::channel` function returns a tuple, the first element of which is the
sending end—the transmitter—and the second element of which is the receiving
end—the receiver. The abbreviations `tx` and `rx` are traditionally used in
many fields for _transmitter_ and _receiver_, respectively, so we name our
variables as such to indicate each end. We’re using a `let` statement with a
pattern that destructures the tuples; we’ll discuss the use of patterns in
`let` statements and destructuring in Chapter 19. For now, know that using a
`let` statement in this way is a convenient approach to extract the pieces of
the tuple returned by `mpsc::channel`.
Let’s move the transmitting end into a spawned thread and have it send one
string so that the spawned thread is communicating with the main thread, as
shown in Listing 16-7. This is like putting a rubber duck in the river upstream
or sending a chat message from one thread to another.
Listing 16-7 (src/main.rs)


The Rust Programming Language › Transfer Data Between Threads with Message Passing

```rust
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });
}
```
Again, we’re using `thread::spawn` to create a new thread and then using `move`
to move `tx` into the closure so that the spawned thread owns `tx`. The spawned
thread needs to own the transmitter to be able to send messages through the
channel.
The transmitter has a `send` method that takes the value we want to send. The
`send` method returns a `Result<T, E>` type, so if the receiver has already
been dropped and there’s nowhere to send a value, the send operation will
return an error. In this example, we’re calling `unwrap` to panic in case of an
error. But in a real application, we would handle it properly: Return to
Chapter 9 to review strategies for proper error handling.
In Listing 16-8, we’ll get the value from the receiver in the main thread. This
is like retrieving the rubber duck from the water at the end of the river or
receiving a chat message.
Listing 16-8 (src/main.rs)
```rust
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });

    let received = rx.recv().unwrap();
    println!("Got: {received}");
}
```


The Rust Programming Language › Transfer Data Between Threads with Message Passing

The receiver has two useful methods: `recv` and `try_recv`. We’re using `recv`,
short for _receive_, which will block the main thread’s execution and wait
until a value is sent down the channel. Once a value is sent, `recv` will
return it in a `Result<T, E>`. When the transmitter closes, `recv` will return
an error to signal that no more values will be coming.
The `try_recv` method doesn’t block, but will instead return a `Result<T, E>`
immediately: an `Ok` value holding a message if one is available and an `Err`
value if there aren’t any messages this time. Using `try_recv` is useful if
this thread has other work to do while waiting for messages: We could write a
loop that calls `try_recv` every so often, handles a message if one is
available, and otherwise does other work for a little while until checking
again.
We’ve used `recv` in this example for simplicity; we don’t have any other work
for the main thread to do other than wait for messages, so blocking the main
thread is appropriate.
When we run the code in Listing 16-8, we’ll see the value printed from the main
thread:
```text
Got: hi
```
Perfect!


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Transferring Ownership Through Channels

The ownership rules play a vital role in message sending because they help you
write safe, concurrent code. Preventing errors in concurrent programming is the
advantage of thinking about ownership throughout your Rust programs. Let’s do
an experiment to show how channels and ownership work together to prevent
problems: We’ll try to use a `val` value in the spawned thread _after_ we’ve
sent it down the channel. Try compiling the code in Listing 16-9 to see why
this code isn’t allowed.
Listing 16-9: Attempting to use `val` after we’ve sent it down the channel (src/main.rs)
```rust,ignore,does_not_compile
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
        println!("val is {val}");
    });

    let received = rx.recv().unwrap();
    println!("Got: {received}");
}
```
Here, we try to print `val` after we’ve sent it down the channel via `tx.send`.
Allowing this would be a bad idea: Once the value has been sent to another
thread, that thread could modify or drop it before we try to use the value
again. Potentially, the other thread’s modifications could cause errors or
unexpected results due to inconsistent or nonexistent data. However, Rust gives
us an error if we try to compile the code in Listing 16-9:


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Transferring Ownership Through Channels

```console
$ cargo run
   Compiling message-passing v0.1.0 (file:///projects/message-passing)
error[E0382]: borrow of moved value: `val`
  --> src/main.rs:10:27
   |
 8 |         let val = String::from("hi");
   |             --- move occurs because `val` has type `String`, which does not implement the `Copy` trait
 9 |         tx.send(val).unwrap();
   |                 --- value moved here
10 |         println!("val is {val}");
   |                           ^^^ value borrowed here after move

For more information about this error, try `rustc --explain E0382`.
error: could not compile `message-passing` (bin "message-passing") due to 1 previous error
```
Our concurrency mistake has caused a compile-time error. The `send` function
takes ownership of its parameter, and when the value is moved the receiver
takes ownership of it. This stops us from accidentally using the value again
after sending it; the ownership system checks that everything is okay.


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Sending Multiple Values

The code in Listing 16-8 compiled and ran, but it didn’t clearly show us that
two separate threads were talking to each other over the channel.
In Listing 16-10, we’ve made some modifications that will prove the code in
Listing 16-8 is running concurrently: The spawned thread will now send multiple
messages and pause for a second between each message.
Listing 16-10: Sending multiple messages and pausing between each one (src/main.rs)
```rust,noplayground
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {received}");
    }
}
```
This time, the spawned thread has a vector of strings that we want to send to
the main thread. We iterate over them, sending each individually, and pause
between each by calling the `thread::sleep` function with a `Duration` value of
one second.
In the main thread, we’re not calling the `recv` function explicitly anymore:
Instead, we’re treating `rx` as an iterator. For each value received, we’re
printing it. When the channel is closed, iteration will end.
When running the code in Listing 16-10, you should see the following output
with a one-second pause in between each line:
```text
Got: hi
Got: from
Got: the
Got: thread
```


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Sending Multiple Values

Because we don’t have any code that pauses or delays in the `for` loop in the
main thread, we can tell that the main thread is waiting to receive values from
the spawned thread.


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Creating Multiple Producers

Earlier we mentioned that `mpsc` was an acronym for _multiple producer, single
consumer_. Let’s put `mpsc` to use and expand the code in Listing 16-10 to
create multiple threads that all send values to the same receiver. We can do so
by cloning the transmitter, as shown in Listing 16-11.
Listing 16-11: Sending multiple messages from multiple producers (src/main.rs)
```rust,noplayground
    // --snip--

    let (tx, rx) = mpsc::channel();

    let tx1 = tx.clone();
    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx1.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        let vals = vec![
            String::from("more"),
            String::from("messages"),
            String::from("for"),
            String::from("you"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {received}");
    }

    // --snip--
```
This time, before we create the first spawned thread, we call `clone` on the
transmitter. This will give us a new transmitter we can pass to the first
spawned thread. We pass the original transmitter to a second spawned thread.
This gives us two threads, each sending different messages to the one receiver.
When you run the code, your output should look something like this:
```text
Got: hi
Got: more
Got: from
Got: messages
Got: for
Got: the
Got: thread
Got: you
```


The Rust Programming Language › Transfer Data Between Threads with Message Passing › Creating Multiple Producers

You might see the values in another order, depending on your system. This is
what makes concurrency interesting as well as difficult. If you experiment with
`thread::sleep`, giving it various values in the different threads, each run
will be more nondeterministic and create different output each time.
Now that we’ve looked at how channels work, let’s look at a different method of
concurrency.


The Rust Programming Language › Shared-State Concurrency

Message passing is a fine way to handle concurrency, but it’s not the only way.
Another method would be for multiple threads to access the same shared data.
Consider this part of the slogan from the Go language documentation again: “Do
not communicate by sharing memory.”
What would communicating by sharing memory look like? In addition, why would
message-passing enthusiasts caution not to use memory sharing?
In a way, channels in any programming language are similar to single ownership
because once you transfer a value down a channel, you should no longer use that
value. Shared-memory concurrency is like multiple ownership: Multiple threads
can access the same memory location at the same time. As you saw in Chapter 15,
where smart pointers made multiple ownership possible, multiple ownership can
add complexity because these different owners need managing. Rust’s type system
and ownership rules greatly assist in getting this management correct. For an
example, let’s look at mutexes, one of the more common concurrency primitives
for shared memory.


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › The API of `Mutex<T>`

_Mutex_ is an abbreviation for _mutual exclusion_, as in a mutex allows only
one thread to access some data at any given time. To access the data in a
mutex, a thread must first signal that it wants access by asking to acquire the
mutex’s lock. The _lock_ is a data structure that is part of the mutex that
keeps track of who currently has exclusive access to the data. Therefore, the
mutex is described as _guarding_ the data it holds via the locking system.
Mutexes have a reputation for being difficult to use because you have to
remember two rules:
1. You must attempt to acquire the lock before using the data.
2. When you’re done with the data that the mutex guards, you must unlock the
   data so that other threads can acquire the lock.
For a real-world metaphor for a mutex, imagine a panel discussion at a
conference with only one microphone. Before a panelist can speak, they have to
ask or signal that they want to use the microphone. When they get the
microphone, they can talk for as long as they want to and then hand the
microphone to the next panelist who requests to speak. If a panelist forgets to
hand the microphone off when they’re finished with it, no one else is able to
speak. If management of the shared microphone goes wrong, the panel won’t work
as planned!
Management of mutexes can be incredibly tricky to get right, which is why so
many people are enthusiastic about channels. However, thanks to Rust’s type
system and ownership rules, you can’t get locking and unlocking wrong.
As an example of how to use a mutex, let’s start by using a mutex in a
single-threaded context, as shown in Listing 16-12.
Listing 16-12 (src/main.rs)

Shared-State Concurrency
Controlling Access with Mutexes
The API of `Mutex<T>`


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › The API of `Mutex<T>`

```rust
use std::sync::Mutex;

fn main() {
    let m = Mutex::new(5);

    {
        let mut num = m.lock().unwrap();
        *num = 6;
    }

    println!("m = {m:?}");
}
```
As with many types, we create a `Mutex<T>` using the associated function `new`.
To access the data inside the mutex, we use the `lock` method to acquire the
lock. This call will block the current thread so that it can’t do any work
until it’s our turn to have the lock.
The call to `lock` would fail if another thread holding the lock panicked. In
that case, no one would ever be able to get the lock, so we’ve chosen to
`unwrap` and have this thread panic if we’re in that situation.
After we’ve acquired the lock, we can treat the return value, named `num` in
this case, as a mutable reference to the data inside. The type system ensures
that we acquire a lock before using the value in `m`. The type of `m` is
`Mutex<i32>`, not `i32`, so we _must_ call `lock` to be able to use the `i32`
value. We can’t forget; the type system won’t let us access the inner `i32`
otherwise.
The call to `lock` returns a type called `MutexGuard`, wrapped in a
`LockResult` that we handled with the call to `unwrap`. The `MutexGuard` type
implements `Deref` to point at our inner data; the type also has a `Drop`
implementation that releases the lock automatically when a `MutexGuard` goes
out of scope, which happens at the end of the inner scope. As a result, we
don’t risk forgetting to release the lock and blocking the mutex from being
used by other threads because the lock release happens automatically.


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Shared Access to `Mutex<T>`

After dropping the lock, we can print the mutex value and see that we were able
to change the inner `i32` to `6`.
Now let’s try to share a value between multiple threads using `Mutex<T>`. We’ll
spin up 10 threads and have them each increment a counter value by 1, so the
counter goes from 0 to 10. The example in Listing 16-13 will have a compiler
error, and we’ll use that error to learn more about using `Mutex<T>` and how
Rust helps us use it correctly.
Listing 16-13 (src/main.rs)
```rust,ignore,does_not_compile
use std::sync::Mutex;
use std::thread;

fn main() {
    let counter = Mutex::new(0);
    let mut handles = vec![];

    for _ in 0..10 {
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();

            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
```
We create a `counter` variable to hold an `i32` inside a `Mutex<T>`, as we did
in Listing 16-12. Next, we create 10 threads by iterating over a range of
numbers. We use `thread::spawn` and give all the threads the same closure: one
that moves the counter into the thread, acquires a lock on the `Mutex<T>` by
calling the `lock` method, and then adds 1 to the value in the mutex. When a
thread finishes running its closure, `num` will go out of scope and release the
lock so that another thread can acquire it.

Shared-State Concurrency
Controlling Access with Mutexes
Shared Access to `Mutex<T>`


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Multiple Ownership with Multiple Threads

In the main thread, we collect all the join handles. Then, as we did in Listing
16-2, we call `join` on each handle to make sure all the threads finish. At
that point, the main thread will acquire the lock and print the result of this
program.
We hinted that this example wouldn’t compile. Now let’s find out why!
```console
$ cargo run
   Compiling shared-state v0.1.0 (file:///projects/shared-state)
error[E0382]: borrow of moved value: `counter`
  --> src/main.rs:21:29
   |
 5 |     let counter = Mutex::new(0);
   |         ------- move occurs because `counter` has type `std::sync::Mutex<i32>`, which does not implement the `Copy` trait
...
 8 |     for _ in 0..10 {
   |     -------------- inside of this loop
 9 |         let handle = thread::spawn(move || {
   |                                    ------- value moved into closure here, in previous iteration of loop
...
21 |     println!("Result: {}", *counter.lock().unwrap());
   |                             ^^^^^^^ value borrowed here after move

For more information about this error, try `rustc --explain E0382`.
error: could not compile `shared-state` (bin "shared-state") due to 1 previous error
```
The error message states that the `counter` value was moved in the previous
iteration of the loop. Rust is telling us that we can’t move the ownership of
lock `counter` into multiple threads. Let’s fix the compiler error with the
multiple-ownership method we discussed in Chapter 15.


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Multiple Ownership with Multiple Threads

In Chapter 15, we gave a value to multiple owners by using the smart pointer
`Rc<T>` to create a reference-counted value. Let’s do the same here and see
what happens. We’ll wrap the `Mutex<T>` in `Rc<T>` in Listing 16-14 and clone
the `Rc<T>` before moving ownership to the thread.
Listing 16-14 (src/main.rs)
```rust,ignore,does_not_compile
use std::rc::Rc;
use std::sync::Mutex;
use std::thread;

fn main() {
    let counter = Rc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Rc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();

            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
```
Once again, we compile and get... different errors! The compiler is teaching us
a lot:


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Multiple Ownership with Multiple Threads

```console
$ cargo run
   Compiling shared-state v0.1.0 (file:///projects/shared-state)
error[E0277]: `Rc<std::sync::Mutex<i32>>` cannot be sent between threads safely
  --> src/main.rs:11:36
   |
11 |           let handle = thread::spawn(move || {
   |                        ------------- ^------
   |                        |             |
   |  ______________________|_____________within this `{closure@src/main.rs:11:36: 11:43}`
   | |                      |
   | |                      required by a bound introduced by this call
12 | |             let mut num = counter.lock().unwrap();
13 | |
14 | |             *num += 1;
15 | |         });
   | |_________^ `Rc<std::sync::Mutex<i32>>` cannot be sent between threads safely
   |
   = help: within `{closure@src/main.rs:11:36: 11:43}`, the trait `Send` is not implemented for `Rc<std::sync::Mutex<i32>>`
note: required because it's used within this closure
  --> src/main.rs:11:36
   |
11 |         let handle = thread::spawn(move || {
   |                                    ^^^^^^^
note: required by a bound in `spawn`
  --> /rustc/2d8144b7880597b6e6d3dfd63a9a9efae3f533d3/library/std/src/thread/functions.rs:125:0

For more information about this error, try `rustc --explain E0277`.
error: could not compile `shared-state` (bin "shared-state") due to 1 previous error
```


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Atomic Reference Counting with `Arc<T>`

Wow, that error message is very wordy! Here’s the important part to focus on:
`` `Rc<Mutex<i32>>` cannot be sent between threads safely ``. The compiler is
also telling us the reason why: `` the trait `Send` is not implemented for
`Rc<Mutex<i32>>` ``. We’ll talk about `Send` in the next section: It’s one of
the traits that ensures that the types we use with threads are meant for use in
concurrent situations.
Unfortunately, `Rc<T>` is not safe to share across threads. When `Rc<T>`
manages the reference count, it adds to the count for each call to `clone` and
subtracts from the count when each clone is dropped. But it doesn’t use any
concurrency primitives to make sure that changes to the count can’t be
interrupted by another thread. This could lead to wrong counts—subtle bugs that
could in turn lead to memory leaks or a value being dropped before we’re done
with it. What we need is a type that is exactly like `Rc<T>`, but that makes
changes to the reference count in a thread-safe way.
Fortunately, `Arc<T>` _is_ a type like `Rc<T>` that is safe to use in
concurrent situations. The _a_ stands for _atomic_, meaning it’s an _atomically
reference-counted_ type. Atomics are an additional kind of concurrency
primitive that we won’t cover in detail here: See the standard library
documentation for `std::sync::atomic` for more
details. At this point, you just need to know that atomics work like primitive
types but are safe to share across threads.

Shared-State Concurrency
Controlling Access with Mutexes
Atomic Reference Counting with `Arc<T>`


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Atomic Reference Counting with `Arc<T>`

You might then wonder why all primitive types aren’t atomic and why standard
library types aren’t implemented to use `Arc<T>` by default. The reason is that
thread safety comes with a performance penalty that you only want to pay when
you really need to. If you’re just performing operations on values within a
single thread, your code can run faster if it doesn’t have to enforce the
guarantees atomics provide.
Let’s return to our example: `Arc<T>` and `Rc<T>` have the same API, so we fix
our program by changing the `use` line, the call to `new`, and the call to
`clone`. The code in Listing 16-15 will finally compile and run.
Listing 16-15 (src/main.rs)
```rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();

            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
```
This code will print the following:
```text
Result: 10
```
We did it! We counted from 0 to 10, which may not seem very impressive, but it
did teach us a lot about `Mutex<T>` and thread safety. You could also use this
program’s structure to do more complicated operations than just incrementing a
counter. Using this strategy, you can divide a calculation into independent
parts, split those parts across threads, and then use a `Mutex<T>` to have each
thread update the final result with its part.


The Rust Programming Language › Shared-State Concurrency › Controlling Access with Mutexes › Atomic Reference Counting with `Arc<T>`

Note that if you are doing simple numerical operations, there are types simpler
than `Mutex<T>` types provided by the `std::sync::atomic` module of the
standard library. These types provide safe, concurrent,
atomic access to primitive types. We chose to use `Mutex<T>` with a primitive
type for this example so that we could concentrate on how `Mutex<T>` works.


The Rust Programming Language › Shared-State Concurrency › Comparing `RefCell<T>`/`Rc<T>` and `Mutex<T>`/`Arc<T>`

You might have noticed that `counter` is immutable but that we could get a
mutable reference to the value inside it; this means `Mutex<T>` provides
interior mutability, as the `Cell` family does. In the same way we used
`RefCell<T>` in Chapter 15 to allow us to mutate contents inside an `Rc<T>`, we
use `Mutex<T>` to mutate contents inside an `Arc<T>`.
Another detail to note is that Rust can’t protect you from all kinds of logic
errors when you use `Mutex<T>`. Recall from Chapter 15 that using `Rc<T>` came
with the risk of creating reference cycles, where two `Rc<T>` values refer to
each other, causing memory leaks. Similarly, `Mutex<T>` comes with the risk of
creating _deadlocks_. These occur when an operation needs to lock two resources
and two threads have each acquired one of the locks, causing them to wait for
each other forever. If you’re interested in deadlocks, try creating a Rust
program that has a deadlock; then, research deadlock mitigation strategies for
mutexes in any language and have a go at implementing them in Rust. The
standard library API documentation for `Mutex<T>` and `MutexGuard` offers
useful information.
We’ll round out this chapter by talking about the `Send` and `Sync` traits and
how we can use them with custom types.


The Rust Programming Language › Extensible Concurrency with `Send` and `Sync`

Interestingly, almost every concurrency feature we’ve talked about so far in
this chapter has been part of the standard library, not the language. Your
options for handling concurrency are not limited to the language or the
standard library; you can write your own concurrency features or use those
written by others.
However, among the key concurrency concepts that are embedded in the language
rather than the standard library are the `std::marker` traits `Send` and `Sync`.


The Rust Programming Language › Extensible Concurrency with `Send` and `Sync` › Transferring Ownership Between Threads

The `Send` marker trait indicates that ownership of values of the type
implementing `Send` can be transferred between threads. Almost every Rust type
implements `Send`, but there are some exceptions, including `Rc<T>`: This
cannot implement `Send` because if you cloned an `Rc<T>` value and tried to
transfer ownership of the clone to another thread, both threads might update
the reference count at the same time. For this reason, `Rc<T>` is implemented
for use in single-threaded situations where you don’t want to pay the
thread-safe performance penalty.
Therefore, Rust’s type system and trait bounds ensure that you can never
accidentally send an `Rc<T>` value across threads unsafely. When we tried to do
this in Listing 16-14, we got the error `` the trait `Send` is not implemented
for `Rc<Mutex<i32>>` ``. When we switched to `Arc<T>`, which does implement
`Send`, the code compiled.
Any type composed entirely of `Send` types is automatically marked as `Send` as
well. Almost all primitive types are `Send`, aside from raw pointers, which
we’ll discuss in Chapter 20.


The Rust Programming Language › Extensible Concurrency with `Send` and `Sync` › Accessing from Multiple Threads

The `Sync` marker trait indicates that it is safe for the type implementing
`Sync` to be referenced from multiple threads. In other words, any type `T`
implements `Sync` if `&T` (an immutable reference to `T`) implements `Send`,
meaning the reference can be sent safely to another thread. Similar to `Send`,
primitive types all implement `Sync`, and types composed entirely of types that
implement `Sync` also implement `Sync`.
The smart pointer `Rc<T>` also doesn’t implement `Sync` for the same reasons
that it doesn’t implement `Send`. The `RefCell<T>` type (which we talked about
in Chapter 15) and the family of related `Cell<T>` types don’t implement
`Sync`. The implementation of borrow checking that `RefCell<T>` does at runtime
is not thread-safe. The smart pointer `Mutex<T>` implements `Sync` and can be
used to share access with multiple threads, as you saw in “Shared Access to
`Mutex<T>`”.


The Rust Programming Language › Extensible Concurrency with `Send` and `Sync` › Implementing `Send` and `Sync` Manually Is Unsafe

Because types composed entirely of other types that implement the `Send` and
`Sync` traits also automatically implement `Send` and `Sync`, we don’t have to
implement those traits manually. As marker traits, they don’t even have any
methods to implement. They’re just useful for enforcing invariants related to
concurrency.
Manually implementing these traits involves implementing unsafe Rust code.
We’ll talk about using unsafe Rust code in Chapter 20; for now, the important
information is that building new concurrent types not made up of `Send` and
`Sync` parts requires careful thought to uphold the safety guarantees. “The
Rustonomicon” has more information about these guarantees and how to
uphold them.


The Rust Programming Language › Summary

This isn’t the last you’ll see of concurrency in this book: The next chapter
focuses on async programming, and the project in Chapter 21 will use the
concepts in this chapter in a more realistic situation than the smaller
examples discussed here.
As mentioned earlier, because very little of how Rust handles concurrency is
part of the language, many concurrency solutions are implemented as crates.
These evolve more quickly than the standard library, so be sure to search
online for the current, state-of-the-art crates to use in multithreaded
situations.
The Rust standard library provides channels for message passing and smart
pointer types, such as `Mutex<T>` and `Arc<T>`, that are safe to use in
concurrent contexts. The type system and the borrow checker ensure that the
code using these solutions won’t end up with data races or invalid references.
Once you get your code to compile, you can rest assured that it will happily
run on multiple threads without the kinds of hard-to-track-down bugs common in
other languages. Concurrent programming is no longer a concept to be afraid of:
Go forth and make your programs concurrent, fearlessly!


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams

Many operations we ask the computer to do can take a while to finish. It would
be nice if we could do something else while we’re waiting for those
long-running processes to complete. Modern computers offer two techniques for
working on more than one operation at a time: parallelism and concurrency. Our
programs’ logic, however, is written in a mostly linear fashion. We’d like to
be able to specify the operations a program should perform and points at which
a function could pause and some other part of the program could run instead,
without needing to specify up front exactly the order and manner in which each
bit of code should run. _Asynchronous programming_ is an abstraction that lets
us express our code in terms of potential pausing points and eventual results
that takes care of the details of coordination for us.
This chapter builds on Chapter 16’s use of threads for parallelism and
concurrency by introducing an alternative approach to writing code: Rust’s
futures, streams, and the `async` and `await` syntax that let us express how
operations could be asynchronous, and the third-party crates that implement
asynchronous runtimes: code that manages and coordinates the execution of
asynchronous operations.
Let’s consider an example. Say you’re exporting a video you’ve created of a
family celebration, an operation that could take anywhere from minutes to
hours. The video export will use as much CPU and GPU power as it can. If you
had only one CPU core and your operating system didn’t pause that export until
it completed—that is, if it executed the export _synchronously_—you couldn’t do
anything else on your computer while that task was running. That would be a
pretty frustrating experience. Fortunately, your computer’s operating system
can, and does, invisibly interrupt the export often enough to let you get other
work done simultaneously.


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams

Now say you’re downloading a video shared by someone else, which can also take
a while but does not take up as much CPU time. In this case, the CPU has to
wait for data to arrive from the network. While you can start reading the data
once it starts to arrive, it might take some time for all of it to show up.
Even once the data is all present, if the video is quite large, it could take
at least a second or two to load it all. That might not sound like much, but
it’s a very long time for a modern processor, which can perform billions of
operations every second. Again, your operating system will invisibly interrupt
your program to allow the CPU to perform other work while waiting for the
network call to finish.
The video export is an example of a _CPU-bound_ or _compute-bound_ operation.
It’s limited by the computer’s potential data processing speed within the CPU
or GPU, and how much of that speed it can dedicate to the operation. The video
download is an example of an _I/O-bound_ operation, because it’s limited by the
speed of the computer’s _input and output_; it can only go as fast as the data
can be sent across the network.
In both of these examples, the operating system’s invisible interrupts provide
a form of concurrency. That concurrency happens only at the level of the entire
program, though: the operating system interrupts one program to let other
programs get work done. In many cases, because we understand our programs at a
much more granular level than the operating system does, we can spot
opportunities for concurrency that the operating system can’t see.


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams

For example, if we’re building a tool to manage file downloads, we should be
able to write our program so that starting one download won’t lock up the UI,
and users should be able to start multiple downloads at the same time. Many
operating system APIs for interacting with the network are _blocking_, though;
that is, they block the program’s progress until the data they’re processing is
completely ready.
Note: This is how _most_ function calls work, if you think about it. However,
the term _blocking_ is usually reserved for function calls that interact with
files, the network, or other resources on the computer, because those are the
cases where an individual program would benefit from the operation being
_non_-blocking.
We could avoid blocking our main thread by spawning a dedicated thread to
download each file. However, the overhead of the system resources used by those
threads would eventually become a problem. It would be preferable if the call
didn’t block in the first place, and instead we could define a number of tasks
that we’d like our program to complete and allow the runtime to choose the best
order and manner in which to run them.
That is exactly what Rust’s _async_ (short for _asynchronous_) abstraction
gives us. In this chapter, you’ll learn all about async as we cover the
following topics:
- How to use Rust’s `async` and `await` syntax and execute asynchronous
  functions with a runtime
- How to use the async model to solve some of the same challenges we looked at
  in Chapter 16
- How multithreading and async provide complementary solutions that you can
  combine in many cases
Before we see how async works in practice, though, we need to take a short
detour to discuss the differences between parallelism and concurrency.


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams › Parallelism and Concurrency

We’ve treated parallelism and concurrency as mostly interchangeable so far. Now
we need to distinguish between them more precisely, because the differences
will show up as we start working.
Consider the different ways a team could split up work on a software project.
You could assign a single member multiple tasks, assign each member one task,
or use a mix of the two approaches.
When an individual works on several different tasks before any of them is
complete, this is _concurrency_. One way to implement concurrency is similar to
having two different projects checked out on your computer, and when you get
bored or stuck on one project, you switch to the other. You’re just one person,
so you can’t make progress on both tasks at the exact same time, but you can
multitask, making progress on one at a time by switching between them (see
Figure 17-1).

Figure 17-1: A concurrent workflow, switching between Task A and Task B

When the team splits up a group of tasks by having each member take one task
and work on it alone, this is _parallelism_. Each person on the team can make
progress at the exact same time (see Figure 17-2).


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams › Parallelism and Concurrency

Figure 17-2: A parallel workflow, where work happens on Task A and Task B independently

In both of these workflows, you might have to coordinate between different
tasks. Maybe you thought the task assigned to one person was totally
independent from everyone else’s work, but it actually requires another person
on the team to finish their task first. Some of the work could be done in
parallel, but some of it was actually _serial_: it could only happen in a
series, one task after the other, as in Figure 17-3.

Figure 17-3: A partially parallel workflow, where work happens on Task A and Task B independently until Task A3 is blocked on the results of Task B3.

Likewise, you might realize that one of your own tasks depends on another of
your tasks. Now your concurrent work has also become serial.


The Rust Programming Language › Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams › Parallelism and Concurrency

Parallelism and concurrency can intersect with each other, too. If you learn
that a colleague is stuck until you finish one of your tasks, you’ll probably
focus all your efforts on that task to “unblock” your colleague. You and your
coworker are no longer able to work in parallel, and you’re also no longer able
to work concurrently on your own tasks.
The same basic dynamics come into play with software and hardware. On a machine
with a single CPU core, the CPU can perform only one operation at a time, but
it can still work concurrently. Using tools such as threads, processes, and
async, the computer can pause one activity and switch to others before
eventually cycling back to that first activity again. On a machine with
multiple CPU cores, it can also do work in parallel. One core can be performing
one task while another core performs a completely unrelated one, and those
operations actually happen at the same time.
Running async code in Rust usually happens concurrently. Depending on the
hardware, the operating system, and the async runtime we are using (more on
async runtimes shortly), that concurrency may also use parallelism under the
hood.
Now, let’s dive into how async programming in Rust actually works.


The Rust Programming Language › Futures and the Async Syntax

The key elements of asynchronous programming in Rust are _futures_ and Rust’s
`async` and `await` keywords.
A _future_ is a value that may not be ready now but will become ready at some
point in the future. (This same concept shows up in many languages, sometimes
under other names such as _task_ or _promise_.) Rust provides a `Future` trait
as a building block so that different async operations can be implemented with
different data structures but with a common interface. In Rust, futures are
types that implement the `Future` trait. Each future holds its own information
about the progress that has been made and what “ready” means.
You can apply the `async` keyword to blocks and functions to specify that they
can be interrupted and resumed. Within an async block or async function, you
can use the `await` keyword to _await a future_ (that is, wait for it to become
ready). Any point where you await a future within an async block or function is
a potential spot for that block or function to pause and resume. The process of
checking with a future to see if its value is available yet is called _polling_.
Some other languages, such as C# and JavaScript, also use `async` and `await`
keywords for async programming. If you’re familiar with those languages, you
may notice some significant differences in how Rust handles the syntax. That’s
for good reason, as we’ll see!


The Rust Programming Language › Futures and the Async Syntax

When writing async Rust, we use the `async` and `await` keywords most of the
time. Rust compiles them into equivalent code using the `Future` trait, much as
it compiles `for` loops into equivalent code using the `Iterator` trait.
Because Rust provides the `Future` trait, though, you can also implement it for
your own data types when you need to. Many of the functions we’ll see
throughout this chapter return types with their own implementations of
`Future`. We’ll return to the definition of the trait at the end of the chapter
and dig into more of how it works, but this is enough detail to keep us moving
forward.
This may all feel a bit abstract, so let’s write our first async program: a
little web scraper. We’ll pass in two URLs from the command line, fetch both of
them concurrently, and return the result of whichever one finishes first. This
example will have a fair bit of new syntax, but don’t worry—we’ll explain
everything you need to know as we go.


The Rust Programming Language › Our First Async Program

To keep the focus of this chapter on learning async rather than juggling parts
of the ecosystem, we’ve created the `trpl` crate (`trpl` is short for “The Rust
Programming Language”). It re-exports all the types, traits, and functions
you’ll need, primarily from the `futures` and
`tokio` crates. The `futures` crate is an official home
for Rust experimentation for async code, and it’s actually where the `Future`
trait was originally designed. Tokio is the most widely used async runtime in
Rust today, especially for web applications. There are other great runtimes out
there, and they may be more suitable for your purposes. We use the `tokio`
crate under the hood for `trpl` because it’s well tested and widely used.
In some cases, `trpl` also renames or wraps the original APIs to keep you
focused on the details relevant to this chapter. If you want to understand what
the crate does, we encourage you to check out its source code.
You’ll be able to see what crate each re-export comes from, and we’ve left
extensive comments explaining what the crate does.
Create a new binary project named `hello-async` and add the `trpl` crate as a
dependency:
```console
$ cargo new hello-async
$ cd hello-async
$ cargo add trpl
```
Now we can use the various pieces provided by `trpl` to write our first async
program. We’ll build a little command line tool that fetches two web pages,
pulls the `<title>` element from each, and prints out the title of whichever
page finishes that whole process first.