mirror of
https://github.com/darkicewolf50/RustBrock.git
synced 2025-06-15 13:04:18 -06:00
started ch16.3
This commit is contained in:
parent
661e8bf5c7
commit
96dbd779e7
40
.obsidian/workspace.json
vendored
40
.obsidian/workspace.json
vendored
@ -24,20 +24,6 @@
|
|||||||
{
|
{
|
||||||
"id": "53b36d00b704136e",
|
"id": "53b36d00b704136e",
|
||||||
"type": "leaf",
|
"type": "leaf",
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Smart Pointers.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Smart Pointers"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "feca3744741d15fc",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
"state": {
|
||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
@ -49,6 +35,20 @@
|
|||||||
"title": "Concurrency"
|
"title": "Concurrency"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "3d0ca0b1691c4c2f",
|
||||||
|
"type": "leaf",
|
||||||
|
"state": {
|
||||||
|
"type": "markdown",
|
||||||
|
"state": {
|
||||||
|
"file": "Shared State Concurrency.md",
|
||||||
|
"mode": "source",
|
||||||
|
"source": false
|
||||||
|
},
|
||||||
|
"icon": "lucide-file",
|
||||||
|
"title": "Shared State Concurrency"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "b104e4647c0ac328",
|
"id": "b104e4647c0ac328",
|
||||||
"type": "leaf",
|
"type": "leaf",
|
||||||
@ -245,10 +245,14 @@
|
|||||||
"command-palette:Open command palette": false
|
"command-palette:Open command palette": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": "feca3744741d15fc",
|
"active": "3d0ca0b1691c4c2f",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
"Smart Pointers.md",
|
|
||||||
"Concurrency.md",
|
"Concurrency.md",
|
||||||
|
"Shared State Concurrency.md",
|
||||||
|
"Smart Pointers.md",
|
||||||
|
"().md",
|
||||||
|
"Simultaneous Code Running.md",
|
||||||
|
"Passing Data Between Threads.md",
|
||||||
"Leaky Reference Cycles.md",
|
"Leaky Reference Cycles.md",
|
||||||
"Test Controls.md",
|
"Test Controls.md",
|
||||||
"Ref Cell Mutability.md",
|
"Ref Cell Mutability.md",
|
||||||
@ -270,10 +274,6 @@
|
|||||||
"Lifetimes.md",
|
"Lifetimes.md",
|
||||||
"2025-02-04.md",
|
"2025-02-04.md",
|
||||||
"data_types.md",
|
"data_types.md",
|
||||||
"Collection of Common Data Structs.md",
|
|
||||||
"Constants.md",
|
|
||||||
"Crates.md",
|
|
||||||
"Data Types.md",
|
|
||||||
"does_not_compile.svg",
|
"does_not_compile.svg",
|
||||||
"Untitled.canvas",
|
"Untitled.canvas",
|
||||||
"Good and Bad Code/Commenting Pratices",
|
"Good and Bad Code/Commenting Pratices",
|
||||||
|
@ -1 +1,72 @@
|
|||||||
# Shared-State Concurrency
|
# Shared-State Concurrency
|
||||||
|
Message passing is not the only way of handling concurrency.
|
||||||
|
|
||||||
|
Another way would be multiple threads to access the same shared data.
|
||||||
|
|
||||||
|
Consider this part of the slogan form the Go language documentation:
|
||||||
|
|
||||||
|
"Do not communicate by sharing memory."
|
||||||
|
|
||||||
|
What would communicating by sharing memory look like?
|
||||||
|
|
||||||
|
Why would message-passing enthusiasts caution not to use memory sharing.
|
||||||
|
|
||||||
|
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 we saw before [Ch15](./Smart%20Pointers.md), where smart pointers made multiple ownership possible.
|
||||||
|
|
||||||
|
This can add complexity because these different owners need managing.
|
||||||
|
|
||||||
|
Rust's type system and ownership rules majority assist in getting this management correct.
|
||||||
|
|
||||||
|
Lets look at one example mutexes, one of the more common concurrency primitives for shared memory.
|
||||||
|
|
||||||
|
## Using Mutexes to Allow Access to Data from One Thread at a Time
|
||||||
|
*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 is currently gas exclusive access to the data.
|
||||||
|
|
||||||
|
The mutex can be described as *guarding* the data it holds via the locking system.
|
||||||
|
|
||||||
|
Mutexes have an associated reputation for being difficult to use because to must remember two rules:
|
||||||
|
- You must attempt to acquire the lock before using the data
|
||||||
|
- When you are done with the data that the mutex guards, you must unlock the data so other threads can acquire the lock
|
||||||
|
|
||||||
|
A real-world metaphor for a mutex would be like imagining 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 off the microphone off when they they are 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.
|
||||||
|
|
||||||
|
This is why so many people are enthusiastic about channels.
|
||||||
|
|
||||||
|
However due to Rust's type system and ownership rules, you can't get locking and unlocking wrong.
|
||||||
|
|
||||||
|
### The API of `Mutex<T>`
|
||||||
|
Here is an example of how to use a mutex.
|
||||||
|
|
||||||
|
We will start by using a mutex in a single threaded context.
|
||||||
|
```rust
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let m = Mutex::new(5);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut num = m.lock().unwrap();
|
||||||
|
*num = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("m = {m:?}");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user