Skip to content

Commit 4b05b3b

Browse files
committed
09_concurrency lab update
1 parent 3186771 commit 4b05b3b

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

content/lessons/09_concurrency/index.md

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
+++
22
title = "Fearless concurrency"
3-
date = 2022-11-28
3+
date = 2024-11-14
44
weight = 1
55
[extra]
6-
lesson_date = 2024-11-21
6+
lesson_date = 2024-11-14
77
+++
88

99
## Parallelism vs Concurrency
@@ -12,16 +12,18 @@ Concurrency is when tasks **can make** progress **independently** of each other.
1212

1313
Parallelism is when multiple tasks **make** progress **at the same time**.
1414

15-
## Concurrency models in Rust
15+
# Concurrency models in Rust
1616

17-
### Threads
17+
## Threads
1818

1919
Nothing unusual here.
2020

2121
Threads can be created with the `thread::spawn` function [docs - please read them!](https://doc.rust-lang.org/std/thread/fn.spawn.html).
2222

2323
This method returns a `JoinHandle<T>` which can be used to wait for the thread to finish. `T` is the type of the thread's return value.
2424

25+
Another way to spawn threads is using [`scope`](https://doc.rust-lang.org/std/thread/fn.scope.html). Threads created in such way are mandatorily joined at the end of the scope, which guarantees that they will borrow items for no longer that the lifetime of the scope. Hence, they can borrow non-`'static` items!
26+
2527
#### Propagating panics
2628

2729
In Rust a panic of one thread doesn't affect the other threads (similar to how Java handles exceptions in threads).
@@ -48,6 +50,36 @@ Normal ownership rules still apply. It means that we cannot mutate the vector in
4850

4951
But what if we need to share some state?
5052

53+
### Send and Sync
54+
55+
They are marker traits used to indicate that a type or a reference to it can be used across threads. See the [nomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html) for more information.
56+
57+
> - A type is `Send` if it is safe to move it (_send_ it) to another thread.
58+
> - A type is `Sync` if it is safe to share (_sync_) between threads (`T` is `Sync` if and only if `&T` is `Send`).
59+
60+
This makes sense, because `Sync` is about _sharing_ object between threads, and `&` is the _shared_ reference.
61+
62+
There is also a great answer on Rust forum, listing + explaining example types that are `!Send` or `!Sync`: https://users.rust-lang.org/t/example-of-a-type-that-is-not-send/59835/3.
63+
64+
For more convenient analysis, examples are listed here:
65+
66+
#### `Send + !Sync`:
67+
68+
- `UnsafeCell` (=> `Cell`, `RefCell`);
69+
70+
#### `!Send + !Sync`:
71+
72+
- `Rc`
73+
- `*const T`, `*mut T` (raw pointers)
74+
75+
#### `!Send + Sync`:
76+
77+
- `MutexGuard` (hint: `!Send` for POSIX reasons)
78+
79+
Exercise for the reader: explain reasons for all limitations of the above types.
80+
81+
## Sharing state between threads
82+
5183
### Message passing
5284

5385
One possible way is to use message passing. We can use a blocking queue (called `mpsc` - ["multi producer single consumer FIFO queue"](https://doc.rust-lang.org/std/sync/mpsc/index.html)) to do it.
@@ -68,11 +100,7 @@ Please read more about them in [the book](https://doc.rust-lang.org/stable/book/
68100

69101
[RwLocks](https://doc.rust-lang.org/std/sync/struct.RwLock.html) are similar to mutexes, but they distinguish between read and write locks.
70102

71-
## Send and Sync
72-
73-
They are marker traits used to indicate that a type or a reference to it can be sent across threads. See the [nomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html) for more information.
74-
75-
## Atomic types
103+
### Atomic types
76104

77105
Atomic types are described in [the docs](https://doc.rust-lang.org/std/sync/atomic/).
78106

@@ -171,7 +199,7 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
171199

172200
#### Exercise for the reader
173201

174-
Why is it impossible to share a reference to a `Mutex` between threads?
202+
Why is it impossible to share a reference to a `Mutex` between threads spawned with `std::thread::spawn`?
175203

176204
## Data parallelism with Rayon
177205

@@ -187,3 +215,7 @@ Why do that? Because thread synchronization is hard! [Rust prevents data races](
187215

188216
- [The Book](https://doc.rust-lang.org/book/ch16-00-concurrency.html)
189217
- [Safely writing code that isn't thread-safe](http://archive.today/WFlZV)
218+
219+
## No assignment this week
220+
221+
Please work on the first iteration of the big project instead.

content/lessons/10_design_patterns/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title = "Design patterns"
33
date = 2022-12-05
44
weight = 1
55
[extra]
6-
lesson_date = 2024-11-14
6+
lesson_date = 2024-11-21
77
+++
88

99
## Object-oriented programming and Rust

0 commit comments

Comments
 (0)