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
+38-10Lines changed: 38 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,32 @@ 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
+
> - A type is `Send` if it is safe to move it (*send* it) to another thread.
57
+
> - A type is `Sync` if it is safe to share (*sync*) between threads (`T` is `Sync` if and only if `&T` is `Send`).
58
+
59
+
This makes sense, because `Sync` is about *sharing* object between threads, and `&` is the *shared* reference.
60
+
61
+
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.
62
+
63
+
For more convenient analysis, examples are listed here:
64
+
65
+
#### `Send + !Sync`:
66
+
-`UnsafeCell` (=> `Cell`, `RefCell`);
67
+
68
+
#### `!Send + !Sync`:
69
+
-`Rc`
70
+
-`*const T`, `*mut T` (raw pointers)
71
+
72
+
#### `!Send + Sync`:
73
+
-`MutexGuard` (hint: `!Send` for POSIX reasons)
74
+
75
+
Exercise for the reader: explain reasons for all limitations of the above types.
76
+
77
+
## Sharing state between threads
78
+
51
79
### Message passing
52
80
53
81
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 +96,7 @@ Please read more about them in [the book](https://doc.rust-lang.org/stable/book/
68
96
69
97
[RwLocks](https://doc.rust-lang.org/std/sync/struct.RwLock.html) are similar to mutexes, but they distinguish between read and write locks.
70
98
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
99
+
### Atomic types
76
100
77
101
Atomic types are described in [the docs](https://doc.rust-lang.org/std/sync/atomic/).
0 commit comments