Skip to content

Use <Listing> preprocessor for chapter 16 #4066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions src/ch16-01-threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-1" file-name="src/main.rs" caption="Creating a new thread to print one thing while the main thread prints something else">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-01/src/main.rs}}
```

<span class="caption">Listing 16-1: Creating a new thread to print one thing
while the main thread prints something else</span>
</Listing>

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
Expand Down Expand Up @@ -96,14 +95,13 @@ call the `join` method on it, will wait for its thread to finish. Listing 16-2
shows how to use the `JoinHandle` of the thread we created in Listing 16-1 and
call `join` to make sure the spawned thread finishes before `main` exits:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-2" file-name="src/main.rs" caption="Saving a `JoinHandle` from `thread::spawn` to guarantee the thread is run to completion">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-02/src/main.rs}}
```

<span class="caption">Listing 16-2: Saving a `JoinHandle` from `thread::spawn`
to guarantee the thread is run to completion</span>
</Listing>

Calling `join` on the handle blocks the thread currently running until the
thread represented by the handle terminates. *Blocking* a thread means that
Expand Down Expand Up @@ -137,12 +135,14 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing file-name="src/main.rs">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs}}
```

</Listing>

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:

Expand Down Expand Up @@ -185,14 +185,13 @@ 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 yet work, as you’ll see in a moment.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-3" file-name="src/main.rs" caption="Attempting to use a vector created by the main thread in another thread">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-03/src/main.rs}}
```

<span class="caption">Listing 16-3: Attempting to use a vector created by the
main thread in another thread</span>
</Listing>

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
Expand All @@ -211,14 +210,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-4" file-name="src/main.rs" caption="A thread with a closure that attempts to capture a reference to `v` from a main thread that drops `v`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-04/src/main.rs}}
```

<span class="caption">Listing 16-4: A thread with a closure that attempts to
capture a reference to `v` from a main thread that drops `v`</span>
</Listing>

If Rust allowed us to run this code, there’s a possibility the spawned thread
would be immediately put in the background without running at all. The spawned
Expand Down Expand Up @@ -246,14 +244,14 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-5" file-name="src/main.rs" caption="Using the `move` keyword to force a closure to take ownership of the values it uses">


```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-05/src/main.rs}}
```

<span class="caption">Listing 16-5: Using the `move` keyword to force a closure
to take ownership of the values it uses</span>
</Listing>

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
Expand Down
25 changes: 10 additions & 15 deletions src/ch16-02-message-passing.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,13 @@ string so 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.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-7" file-name="src/main.rs" caption="Moving `tx` to a spawned thread and sending “hi”">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-07/src/main.rs}}
```

<span class="caption">Listing 16-7: Moving `tx` to a spawned thread and sending
“hi”</span>
</Listing>

Again, we’re using `thread::spawn` to create a new thread and then using `move`
to move `tx` into the closure so the spawned thread owns `tx`. The spawned
Expand All @@ -89,14 +88,13 @@ In Listing 16-8, we’ll get the value from the receiver in the main thread. Thi
is like retrieving the rubber duck from the water at the end of the river or
receiving a chat message.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-8" file-name="src/main.rs" caption="Receiving the value “hi” in the main thread and printing it">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-08/src/main.rs}}
```

<span class="caption">Listing 16-8: Receiving the value “hi” in the main thread
and printing it</span>
</Listing>

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
Expand Down Expand Up @@ -139,14 +137,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-9" file-name="src/main.rs" caption="Attempting to use `val` after we’ve sent it down the channel">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-09/src/main.rs}}
```

<span class="caption">Listing 16-9: Attempting to use `val` after we’ve sent it
down the channel</span>
</Listing>

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
Expand All @@ -172,14 +169,13 @@ two separate threads were talking to each other over the channel. In Listing
running concurrently: the spawned thread will now send multiple messages and
pause for a second between each message.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-10" file-name="src/main.rs" caption="Sending multiple messages and pausing between each">

```rust,noplayground
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-10/src/main.rs}}
```

<span class="caption">Listing 16-10: Sending multiple messages and pausing
between each</span>
</Listing>

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
Expand Down Expand Up @@ -215,14 +211,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-11" file-name="src/main.rs" caption="Sending multiple messages from multiple producers">

```rust,noplayground
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-11/src/main.rs:here}}
```

<span class="caption">Listing 16-11: Sending multiple messages from multiple
producers</span>
</Listing>

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
Expand Down
20 changes: 8 additions & 12 deletions src/ch16-03-shared-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-12" file-name="src/main.rs" caption="Exploring the API of `Mutex<T>` in a single-threaded context for simplicity">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-12/src/main.rs}}
```

<span class="caption">Listing 16-12: Exploring the API of `Mutex<T>` in a
single-threaded context for simplicity</span>
</Listing>

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
Expand Down Expand Up @@ -98,14 +97,13 @@ the counter goes from 0 to 10. The next 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.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-13" file-name="src/main.rs" caption="Ten threads each increment a counter guarded by a `Mutex<T>`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-13/src/main.rs}}
```

<span class="caption">Listing 16-13: Ten threads each increment a counter
guarded by a `Mutex<T>`</span>
</Listing>

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
Expand Down Expand Up @@ -138,14 +136,13 @@ In Chapter 15, we gave a value multiple owners by using the smart pointer
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.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-14" file-name="src/main.rs" caption="Attempting to use `Rc<T>` to allow multiple threads to own the `Mutex<T>`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-14/src/main.rs}}
```

<span class="caption">Listing 16-14: Attempting to use `Rc<T>` to allow
multiple threads to own the `Mutex<T>`</span>
</Listing>

Once again, we compile and get... different errors! The compiler is teaching us
a lot.
Expand Down Expand Up @@ -191,14 +188,13 @@ 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:

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-15" file-name="src/main.rs" caption="Using an `Arc<T>` to wrap the `Mutex<T>` to be able to share ownership across multiple threads">

```rust
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-15/src/main.rs}}
```

<span class="caption">Listing 16-15: Using an `Arc<T>` to wrap the `Mutex<T>`
to be able to share ownership across multiple threads</span>
</Listing>

This code will print the following:

Expand Down