You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/lessons/09_concurrency/index.md
+42-10Lines changed: 42 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,9 @@
1
1
+++
2
2
title = "Fearless concurrency"
3
-
date = 2022-11-28
3
+
date = 2024-11-14
4
4
weight = 1
5
5
[extra]
6
-
lesson_date = 2024-11-21
6
+
lesson_date = 2024-11-14
7
7
+++
8
8
9
9
## Parallelism vs Concurrency
@@ -12,16 +12,18 @@ Concurrency is when tasks **can make** progress **independently** of each other.
12
12
13
13
Parallelism is when multiple tasks **make** progress **at the same time**.
14
14
15
-
##Concurrency models in Rust
15
+
# Concurrency models in Rust
16
16
17
-
###Threads
17
+
## Threads
18
18
19
19
Nothing unusual here.
20
20
21
21
Threads can be created with the `thread::spawn` function [docs - please read them!](https://doc.rust-lang.org/std/thread/fn.spawn.html).
22
22
23
23
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.
24
24
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
+
25
27
#### Propagating panics
26
28
27
29
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
48
50
49
51
But what if we need to share some state?
50
52
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
+
51
83
### Message passing
52
84
53
85
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/
68
100
69
101
[RwLocks](https://doc.rust-lang.org/std/sync/struct.RwLock.html) are similar to mutexes, but they distinguish between read and write locks.
70
102
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
76
104
77
105
Atomic types are described in [the docs](https://doc.rust-lang.org/std/sync/atomic/).
0 commit comments