|
2 | 2 |
|
3 | 3 | # Introduction
|
4 | 4 |
|
5 |
| -The designers of Rust designed the language from the ground up to support pervasive |
6 |
| -and safe concurrency through lightweight, memory-isolated tasks and |
7 |
| -message passing. |
8 |
| - |
9 |
| -Rust tasks are not the same as traditional threads: rather, they are more like |
10 |
| -_green threads_. The Rust runtime system schedules tasks cooperatively onto a |
11 |
| -small number of operating system threads. Because tasks are significantly |
| 5 | +Rust provides safe concurrency through a combination |
| 6 | +of lightweight, memory-isolated tasks and message passing. |
| 7 | +This tutorial will describe the concurrency model in Rust, how it |
| 8 | +relates to the Rust type system, and introduce |
| 9 | +the fundamental library abstractions for constructing concurrent programs. |
| 10 | + |
| 11 | +Rust tasks are not the same as traditional threads: rather, |
| 12 | +they are considered _green threads_, lightweight units of execution that the Rust |
| 13 | +runtime schedules cooperatively onto a small number of operating system threads. |
| 14 | +On a multi-core system Rust tasks will be scheduled in parallel by default. |
| 15 | +Because tasks are significantly |
12 | 16 | cheaper to create than traditional threads, Rust can create hundreds of
|
13 | 17 | thousands of concurrent tasks on a typical 32-bit system.
|
| 18 | +In general, all Rust code executes inside a task, including the `main` function. |
| 19 | + |
| 20 | +In order to make efficient use of memory Rust tasks have dynamically sized stacks. |
| 21 | +A task begins its life with a small |
| 22 | +amount of stack space (currently in the low thousands of bytes, depending on |
| 23 | +platform), and acquires more stack as needed. |
| 24 | +Unlike in languages such as C, a Rust task cannot accidentally write to |
| 25 | +memory beyond the end of the stack, causing crashes or worse. |
14 | 26 |
|
15 |
| -Tasks provide failure isolation and recovery. When an exception occurs in Rust |
16 |
| -code (as a result of an explicit call to `fail!()`, an assertion failure, or |
17 |
| -another invalid operation), the runtime system destroys the entire |
| 27 | +Tasks provide failure isolation and recovery. When a fatal error occurs in Rust |
| 28 | +code as a result of an explicit call to `fail!()`, an assertion failure, or |
| 29 | +another invalid operation, the runtime system destroys the entire |
18 | 30 | task. Unlike in languages such as Java and C++, there is no way to `catch` an
|
19 | 31 | exception. Instead, tasks may monitor each other for failure.
|
20 | 32 |
|
21 |
| -Rust tasks have dynamically sized stacks. A task begins its life with a small |
22 |
| -amount of stack space (currently in the low thousands of bytes, depending on |
23 |
| -platform), and acquires more stack as needed. Unlike in languages such as C, a |
24 |
| -Rust task cannot run off the end of the stack. However, tasks do have a stack |
25 |
| -budget. If a Rust task exceeds its stack budget, then it will fail safely: |
26 |
| -with a checked exception. |
27 |
| - |
28 | 33 | Tasks use Rust's type system to provide strong memory safety guarantees. In
|
29 | 34 | particular, the type system guarantees that tasks cannot share mutable state
|
30 | 35 | with each other. Tasks communicate with each other by transferring _owned_
|
31 | 36 | data through the global _exchange heap_.
|
32 | 37 |
|
33 |
| -This tutorial explains the basics of tasks and communication in Rust, |
34 |
| -explores some typical patterns in concurrent Rust code, and finally |
35 |
| -discusses some of the more unusual synchronization types in the standard |
36 |
| -library. |
37 |
| - |
38 |
| -> ***Warning:*** This tutorial is incomplete |
39 |
| -
|
40 | 38 | ## A note about the libraries
|
41 | 39 |
|
42 | 40 | While Rust's type system provides the building blocks needed for safe
|
43 | 41 | and efficient tasks, all of the task functionality itself is implemented
|
44 | 42 | in the core and standard libraries, which are still under development
|
45 |
| -and do not always present a consistent interface. |
46 |
| - |
47 |
| -In particular, there are currently two independent modules that provide a |
48 |
| -message passing interface to Rust code: `core::comm` and `core::pipes`. |
49 |
| -`core::comm` is an older, less efficient system that is being phased out in |
50 |
| -favor of `pipes`. At some point, we will remove the existing `core::comm` API |
51 |
| -and move the user-facing portions of `core::pipes` to `core::comm`. In this |
52 |
| -tutorial, we discuss `pipes` and ignore the `comm` API. |
| 43 | +and do not always present a consistent or complete interface. |
53 | 44 |
|
54 | 45 | For your reference, these are the standard modules involved in Rust
|
55 | 46 | concurrency at this writing.
|
56 | 47 |
|
57 | 48 | * [`core::task`] - All code relating to tasks and task scheduling
|
58 |
| -* [`core::comm`] - The deprecated message passing API |
59 |
| -* [`core::pipes`] - The new message passing infrastructure and API |
60 |
| -* [`std::comm`] - Higher level messaging types based on `core::pipes` |
| 49 | +* [`core::comm`] - The message passing interface |
| 50 | +* [`core::pipes`] - The underlying messaging infrastructure |
| 51 | +* [`std::comm`] - Additional messaging types based on `core::pipes` |
61 | 52 | * [`std::sync`] - More exotic synchronization tools, including locks
|
62 |
| -* [`std::arc`] - The ARC (atomic reference counted) type, for safely sharing |
63 |
| - immutable data |
64 |
| -* [`std::par`] - Some basic tools for implementing parallel algorithms |
| 53 | +* [`std::arc`] - The ARC (atomically reference counted) type, |
| 54 | + for safely sharing immutable data |
65 | 55 |
|
66 | 56 | [`core::task`]: core/task.html
|
67 | 57 | [`core::comm`]: core/comm.html
|
68 | 58 | [`core::pipes`]: core/pipes.html
|
69 | 59 | [`std::comm`]: std/comm.html
|
70 | 60 | [`std::sync`]: std/sync.html
|
71 | 61 | [`std::arc`]: std/arc.html
|
72 |
| -[`std::par`]: std/par.html |
73 | 62 |
|
74 | 63 | # Basics
|
75 | 64 |
|
|
0 commit comments