100 exercises to learn Rust

This commit is contained in:
LukeMathWalker
2024-05-12 22:21:03 +02:00
commit 5edebf6cf2
309 changed files with 13173 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
# Scoped threads
All the lifetime issues we discussed so far have a common source:
the spawned thread can outlive its parent.
We can sidestep this issue by using **scoped threads**.
```rust
let v = vec![1, 2, 3];
let midpoint = v.len() / 2;
std::thread::scope(|scope| {
scope.spawn(|| {
let first = &v[..midpoint];
println!("Here's the first half of v: {first:?}");
});
scope.spawn(|| {
let second = &v[midpoint..];
println!("Here's the second half of v: {second:?}");
});
});
println!("Here's v: {v:?}");
```
Let's unpack what's happening.
## `scope`
The `std::thread::scope` function creates a new **scope**.
`std::thread::scope` takes as input a closure, with a single argument: a `Scope` instance.
## Scoped spawns
`Scope` exposes a `spawn` method.
Unlike `std::thread::spawn`, all threads spawned using a `Scope` will be
**automatically joined** when the scope ends.
If we were to "translate" the previous example to `std::thread::spawn`,
it'd look like this:
```rust
let v = vec![1, 2, 3];
let midpoint = v.len() / 2;
let handle1 = std::thread::spawn(|| {
let first = &v[..midpoint];
println!("Here's the first half of v: {first:?}");
});
let handle2 = std::thread::spawn(|| {
let second = &v[midpoint..];
println!("Here's the second half of v: {second:?}");
});
handle1.join().unwrap();
handle2.join().unwrap();
println!("Here's v: {v:?}");
```
## Borrowing from the environment
The translated example wouldn't compile, though: the compiler would complain
that `&v` can't be used from our spawned threads since its lifetime isn't
`'static`.
That's not an issue with `std::thread::scope`—you can **safely borrow from the environment**.
In our example, `v` is created before the spawning points.
It will only be dropped _after_ `scope` returns. At the same time,
all threads spawned inside `scope` are guaranteed `v` is dropped,
therefore there is no risk of having dangling references.
The compiler won't complain!