|
2 | 2 |
|
3 | 3 | # Introduction
|
4 | 4 |
|
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 |
| 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 |
16 | 12 | cheaper to create than traditional threads, Rust can create hundreds of
|
17 | 13 | 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. |
26 | 14 |
|
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 |
| 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 |
30 | 18 | task. Unlike in languages such as Java and C++, there is no way to `catch` an
|
31 | 19 | exception. Instead, tasks may monitor each other for failure.
|
32 | 20 |
|
| 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 | + |
33 | 28 | Tasks use Rust's type system to provide strong memory safety guarantees. In
|
34 | 29 | particular, the type system guarantees that tasks cannot share mutable state
|
35 | 30 | with each other. Tasks communicate with each other by transferring _owned_
|
36 | 31 | data through the global _exchange heap_.
|
37 | 32 |
|
| 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 | +
|
38 | 40 | ## A note about the libraries
|
39 | 41 |
|
40 | 42 | While Rust's type system provides the building blocks needed for safe
|
41 | 43 | and efficient tasks, all of the task functionality itself is implemented
|
42 | 44 | in the core and standard libraries, which are still under development
|
43 |
| -and do not always present a consistent or complete interface. |
| 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. |
44 | 53 |
|
45 | 54 | For your reference, these are the standard modules involved in Rust
|
46 | 55 | concurrency at this writing.
|
47 | 56 |
|
48 | 57 | * [`core::task`] - All code relating to tasks and task scheduling
|
49 |
| -* [`core::comm`] - The message passing interface |
50 |
| -* [`core::pipes`] - The underlying messaging infrastructure |
51 |
| -* [`std::comm`] - Additional messaging types based on `core::pipes` |
| 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` |
52 | 61 | * [`std::sync`] - More exotic synchronization tools, including locks
|
53 |
| -* [`std::arc`] - The ARC (atomically reference counted) type, |
54 |
| - for safely sharing immutable data |
| 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 |
55 | 65 |
|
56 | 66 | [`core::task`]: core/task.html
|
57 | 67 | [`core::comm`]: core/comm.html
|
58 | 68 | [`core::pipes`]: core/pipes.html
|
59 | 69 | [`std::comm`]: std/comm.html
|
60 | 70 | [`std::sync`]: std/sync.html
|
61 | 71 | [`std::arc`]: std/arc.html
|
| 72 | +[`std::par`]: std/par.html |
62 | 73 |
|
63 | 74 | # Basics
|
64 | 75 |
|
|
0 commit comments