Skip to content

Commit b8ffad5

Browse files
committed
s/task/thread/g
A part of #20038
1 parent d10642e commit b8ffad5

File tree

11 files changed

+233
-240
lines changed

11 files changed

+233
-240
lines changed

src/doc/guide-tasks.md

+56-56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
% The Rust Tasks and Communication Guide
1+
% The Rust Threads and Communication Guide
22

3-
**NOTE** This guide is badly out of date an needs to be rewritten.
3+
**NOTE** This guide is badly out of date and needs to be rewritten.
44

55
# Introduction
66

@@ -9,36 +9,36 @@ primitives. This guide will describe the concurrency model in Rust, how it
99
relates to the Rust type system, and introduce the fundamental library
1010
abstractions for constructing concurrent programs.
1111

12-
Tasks provide failure isolation and recovery. When a fatal error occurs in Rust
12+
Threads provide failure isolation and recovery. When a fatal error occurs in Rust
1313
code as a result of an explicit call to `panic!()`, an assertion failure, or
14-
another invalid operation, the runtime system destroys the entire task. Unlike
14+
another invalid operation, the runtime system destroys the entire thread. Unlike
1515
in languages such as Java and C++, there is no way to `catch` an exception.
16-
Instead, tasks may monitor each other to see if they panic.
16+
Instead, threads may monitor each other to see if they panic.
1717

18-
Tasks use Rust's type system to provide strong memory safety guarantees. In
19-
particular, the type system guarantees that tasks cannot induce a data race
18+
Threads use Rust's type system to provide strong memory safety guarantees. In
19+
particular, the type system guarantees that threads cannot induce a data race
2020
from shared mutable state.
2121

2222
# Basics
2323

24-
At its simplest, creating a task is a matter of calling the `spawn` function
25-
with a closure argument. `spawn` executes the closure in the new task.
24+
At its simplest, creating a thread is a matter of calling the `spawn` function
25+
with a closure argument. `spawn` executes the closure in the new thread.
2626

2727
```{rust,ignore}
28-
# use std::task::spawn;
28+
# use std::thread::spawn;
2929
30-
// Print something profound in a different task using a named function
31-
fn print_message() { println!("I am running in a different task!"); }
30+
// Print something profound in a different thread using a named function
31+
fn print_message() { println!("I am running in a different thread!"); }
3232
spawn(print_message);
3333
3434
// Alternatively, use a `move ||` expression instead of a named function.
3535
// `||` expressions evaluate to an unnamed closure. The `move` keyword
3636
// indicates that the closure should take ownership of any variables it
3737
// touches.
38-
spawn(move || println!("I am also running in a different task!"));
38+
spawn(move || println!("I am also running in a different thread!"));
3939
```
4040

41-
In Rust, a task is not a concept that appears in the language semantics.
41+
In Rust, a thread is not a concept that appears in the language semantics.
4242
Instead, Rust's type system provides all the tools necessary to implement safe
4343
concurrency: particularly, ownership. The language leaves the implementation
4444
details to the standard library.
@@ -49,26 +49,26 @@ argument a closure (of type `F`) that it will run exactly once. This
4949
closure is limited to capturing `Send`-able data from its environment
5050
(that is, data which is deeply owned). Limiting the closure to `Send`
5151
ensures that `spawn` can safely move the entire closure and all its
52-
associated state into an entirely different task for execution.
52+
associated state into an entirely different thread for execution.
5353

5454
```{rust,ignore}
55-
# use std::task::spawn;
56-
# fn generate_task_number() -> int { 0 }
55+
# use std::thread::spawn;
56+
# fn generate_thread_number() -> int { 0 }
5757
// Generate some state locally
58-
let child_task_number = generate_task_number();
58+
let child_thread_number = generate_thread_number();
5959
6060
spawn(move || {
61-
// Capture it in the remote task. The `move` keyword indicates
62-
// that this closure should move `child_task_number` into its
61+
// Capture it in the remote thread. The `move` keyword indicates
62+
// that this closure should move `child_thread_number` into its
6363
// environment, rather than capturing a reference into the
6464
// enclosing stack frame.
65-
println!("I am child number {}", child_task_number);
65+
println!("I am child number {}", child_thread_number);
6666
});
6767
```
6868

6969
## Communication
7070

71-
Now that we have spawned a new task, it would be nice if we could communicate
71+
Now that we have spawned a new thread, it would be nice if we could communicate
7272
with it. For this, we use *channels*. A channel is simply a pair of endpoints:
7373
one for sending messages and another for receiving messages.
7474

@@ -78,7 +78,7 @@ of a channel, and a **receiver** is the receiving endpoint. Consider the followi
7878
example of calculating two results concurrently:
7979

8080
```{rust,ignore}
81-
# use std::task::spawn;
81+
# use std::thread::spawn;
8282
8383
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
8484
@@ -102,12 +102,12 @@ into its component parts).
102102
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
103103
```
104104

105-
The child task will use the sender to send data to the parent task, which will
105+
The child thread will use the sender to send data to the parent thread, which will
106106
wait to receive the data on the receiver. The next statement spawns the child
107-
task.
107+
thread.
108108

109109
```{rust,ignore}
110-
# use std::task::spawn;
110+
# use std::thread::spawn;
111111
# fn some_expensive_computation() -> int { 42 }
112112
# let (tx, rx) = channel();
113113
spawn(move || {
@@ -116,10 +116,10 @@ spawn(move || {
116116
});
117117
```
118118

119-
Notice that the creation of the task closure transfers `tx` to the child task
119+
Notice that the creation of the thread closure transfers `tx` to the child thread
120120
implicitly: the closure captures `tx` in its environment. Both `Sender` and
121-
`Receiver` are sendable types and may be captured into tasks or otherwise
122-
transferred between them. In the example, the child task runs an expensive
121+
`Receiver` are sendable types and may be captured into threads or otherwise
122+
transferred between them. In the example, the child thread runs an expensive
123123
computation, then sends the result over the captured channel.
124124

125125
Finally, the parent continues with some other expensive computation, then waits
@@ -137,7 +137,7 @@ The `Sender` and `Receiver` pair created by `channel` enables efficient
137137
communication between a single sender and a single receiver, but multiple
138138
senders cannot use a single `Sender` value, and multiple receivers cannot use a
139139
single `Receiver` value. What if our example needed to compute multiple
140-
results across a number of tasks? The following program is ill-typed:
140+
results across a number of threads? The following program is ill-typed:
141141

142142
```{rust,ignore}
143143
# fn some_expensive_computation() -> int { 42 }
@@ -160,7 +160,7 @@ Instead we can clone the `tx`, which allows for multiple senders.
160160
let (tx, rx) = channel();
161161
162162
for init_val in range(0u, 3) {
163-
// Create a new channel handle to distribute to the child task
163+
// Create a new channel handle to distribute to the child thread
164164
let child_tx = tx.clone();
165165
spawn(move || {
166166
child_tx.send(some_expensive_computation(init_val));
@@ -172,7 +172,7 @@ let result = rx.recv() + rx.recv() + rx.recv();
172172
```
173173

174174
Cloning a `Sender` produces a new handle to the same channel, allowing multiple
175-
tasks to send data to a single receiver. It upgrades the channel internally in
175+
threads to send data to a single receiver. It upgrades the channel internally in
176176
order to allow this functionality, which means that channels that are not
177177
cloned can avoid the overhead required to handle multiple senders. But this
178178
fact has no bearing on the channel's usage: the upgrade is transparent.
@@ -182,9 +182,9 @@ simply use three `Sender` pairs, but it serves to illustrate the point. For
182182
reference, written with multiple streams, it might look like the example below.
183183

184184
```{rust,ignore}
185-
# use std::task::spawn;
185+
# use std::thread::spawn;
186186
187-
// Create a vector of ports, one for each child task
187+
// Create a vector of ports, one for each child thread
188188
let rxs = Vec::from_fn(3, |init_val| {
189189
let (tx, rx) = channel();
190190
spawn(move || {
@@ -256,18 +256,18 @@ fn main() {
256256

257257
## Sharing without copying: Arc
258258

259-
To share data between tasks, a first approach would be to only use channel as
259+
To share data between threads, a first approach would be to only use channel as
260260
we have seen previously. A copy of the data to share would then be made for
261-
each task. In some cases, this would add up to a significant amount of wasted
261+
each thread. In some cases, this would add up to a significant amount of wasted
262262
memory and would require copying the same data more than necessary.
263263

264264
To tackle this issue, one can use an Atomically Reference Counted wrapper
265265
(`Arc`) as implemented in the `sync` library of Rust. With an Arc, the data
266-
will no longer be copied for each task. The Arc acts as a reference to the
266+
will no longer be copied for each thread. The Arc acts as a reference to the
267267
shared data and only this reference is shared and cloned.
268268

269269
Here is a small example showing how to use Arcs. We wish to run concurrently
270-
several computations on a single large vector of floats. Each task needs the
270+
several computations on a single large vector of floats. Each thread needs the
271271
full vector to perform its duty.
272272

273273
```{rust,ignore}
@@ -284,10 +284,10 @@ fn main() {
284284
let numbers_arc = Arc::new(numbers);
285285
286286
for num in range(1u, 10) {
287-
let task_numbers = numbers_arc.clone();
287+
let thread_numbers = numbers_arc.clone();
288288
289289
spawn(move || {
290-
println!("{}-norm = {}", num, pnorm(task_numbers.as_slice(), num));
290+
println!("{}-norm = {}", num, pnorm(thread_numbers.as_slice(), num));
291291
});
292292
}
293293
}
@@ -306,8 +306,8 @@ let numbers_arc = Arc::new(numbers);
306306
# }
307307
```
308308

309-
and a clone is captured for each task via a procedure. This only copies
310-
the wrapper and not its contents. Within the task's procedure, the captured
309+
and a clone is captured for each thread via a procedure. This only copies
310+
the wrapper and not its contents. Within the thread's procedure, the captured
311311
Arc reference can be used as a shared reference to the underlying vector as
312312
if it were local.
313313

@@ -319,29 +319,29 @@ if it were local.
319319
# let numbers=Vec::from_fn(1000000, |_| rand::random::<f64>());
320320
# let numbers_arc = Arc::new(numbers);
321321
# let num = 4;
322-
let task_numbers = numbers_arc.clone();
322+
let thread_numbers = numbers_arc.clone();
323323
spawn(move || {
324-
// Capture task_numbers and use it as if it was the underlying vector
325-
println!("{}-norm = {}", num, pnorm(task_numbers.as_slice(), num));
324+
// Capture thread_numbers and use it as if it was the underlying vector
325+
println!("{}-norm = {}", num, pnorm(thread_numbers.as_slice(), num));
326326
});
327327
# }
328328
```
329329

330-
# Handling task panics
330+
# Handling thread panics
331331

332332
Rust has a built-in mechanism for raising exceptions. The `panic!()` macro
333333
(which can also be written with an error string as an argument: `panic!(
334334
~reason)`) and the `assert!` construct (which effectively calls `panic!()` if a
335-
boolean expression is false) are both ways to raise exceptions. When a task
336-
raises an exception, the task unwinds its stack—running destructors and
335+
boolean expression is false) are both ways to raise exceptions. When a thread
336+
raises an exception, the thread unwinds its stack—running destructors and
337337
freeing memory along the way—and then exits. Unlike exceptions in C++,
338-
exceptions in Rust are unrecoverable within a single task: once a task panics,
338+
exceptions in Rust are unrecoverable within a single thread: once a thread panics,
339339
there is no way to "catch" the exception.
340340

341-
While it isn't possible for a task to recover from panicking, tasks may notify
341+
While it isn't possible for a thread to recover from panicking, threads may notify
342342
each other if they panic. The simplest way of handling a panic is with the
343343
`try` function, which is similar to `spawn`, but immediately blocks and waits
344-
for the child task to finish. `try` returns a value of type
344+
for the child thread to finish. `try` returns a value of type
345345
`Result<T, Box<Any + Send>>`. `Result` is an `enum` type with two variants:
346346
`Ok` and `Err`. In this case, because the type arguments to `Result` are `int`
347347
and `()`, callers can pattern-match on a result to check whether it's an `Ok`
@@ -364,19 +364,19 @@ assert!(result.is_err());
364364

365365
Unlike `spawn`, the function spawned using `try` may return a value, which
366366
`try` will dutifully propagate back to the caller in a [`Result`] enum. If the
367-
child task terminates successfully, `try` will return an `Ok` result; if the
368-
child task panics, `try` will return an `Error` result.
367+
child thread terminates successfully, `try` will return an `Ok` result; if the
368+
child thread panics, `try` will return an `Error` result.
369369

370370
[`Result`]: std/result/index.html
371371

372-
> *Note:* A panicked task does not currently produce a useful error
372+
> *Note:* A panicked thread does not currently produce a useful error
373373
> value (`try` always returns `Err(())`). In the
374-
> future, it may be possible for tasks to intercept the value passed to
374+
> future, it may be possible for threads to intercept the value passed to
375375
> `panic!()`.
376376
377377
But not all panics are created equal. In some cases you might need to abort
378378
the entire program (perhaps you're writing an assert which, if it trips,
379379
indicates an unrecoverable logic error); in other cases you might want to
380380
contain the panic at a certain boundary (perhaps a small piece of input from
381381
the outside world, which you happen to be processing in parallel, is malformed
382-
such that the processing task cannot proceed).
382+
such that the processing thread cannot proceed).

0 commit comments

Comments
 (0)