Skip to content

Commit e72adca

Browse files
committed
Fallout: move from scoped to spawn
1 parent 6e0fb70 commit e72adca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+128
-124
lines changed

src/doc/intro.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ safe concurrent programs.
389389
Here's an example of a concurrent Rust program:
390390
391391
```{rust}
392+
# #![feature(scoped)]
392393
use std::thread;
393394
394395
fn main() {
@@ -421,6 +422,7 @@ problem.
421422
Let's see an example. This Rust code will not compile:
422423
423424
```{rust,ignore}
425+
# #![feature(scoped)]
424426
use std::thread;
425427
426428
fn main() {
@@ -467,6 +469,7 @@ that our mutation doesn't cause a data race.
467469
Here's what using a Mutex looks like:
468470
469471
```{rust}
472+
# #![feature(scoped)]
470473
use std::thread;
471474
use std::sync::Mutex;
472475
@@ -527,6 +530,7 @@ As an example, Rust's ownership system is _entirely_ at compile time. The
527530
safety check that makes this an error about moved values:
528531
529532
```{rust,ignore}
533+
# #![feature(scoped)]
530534
use std::thread;
531535
532536
fn main() {

src/doc/trpl/concurrency.md

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,68 +56,35 @@ place!
5656

5757
## Threads
5858

59-
Rust's standard library provides a library for 'threads', which allow you to
59+
Rust's standard library provides a library for threads, which allow you to
6060
run Rust code in parallel. Here's a basic example of using `std::thread`:
6161

6262
```
6363
use std::thread;
6464
6565
fn main() {
66-
thread::scoped(|| {
66+
thread::spawn(|| {
6767
println!("Hello from a thread!");
6868
});
6969
}
7070
```
7171

72-
The `thread::scoped()` method accepts a closure, which is executed in a new
73-
thread. It's called `scoped` because this thread returns a join guard:
72+
The `thread::spawn()` method accepts a closure, which is executed in a
73+
new thread. It returns a handle to the thread, that can be used to
74+
wait for the child thread to finish and extract its result:
7475

7576
```
7677
use std::thread;
7778
7879
fn main() {
79-
let guard = thread::scoped(|| {
80-
println!("Hello from a thread!");
80+
let handle = thread::spawn(|| {
81+
"Hello from a thread!"
8182
});
8283
83-
// guard goes out of scope here
84+
println!("{}", handle.join().unwrap());
8485
}
8586
```
8687

87-
When `guard` goes out of scope, it will block execution until the thread is
88-
finished. If we didn't want this behaviour, we could use `thread::spawn()`:
89-
90-
```
91-
use std::thread;
92-
93-
fn main() {
94-
thread::spawn(|| {
95-
println!("Hello from a thread!");
96-
});
97-
98-
thread::sleep_ms(50);
99-
}
100-
```
101-
102-
We need to `sleep` here because when `main()` ends, it kills all of the
103-
running threads.
104-
105-
[`scoped`](std/thread/struct.Builder.html#method.scoped) has an interesting
106-
type signature:
107-
108-
```text
109-
fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T>
110-
where T: Send + 'a,
111-
F: FnOnce() -> T,
112-
F: Send + 'a
113-
```
114-
115-
Specifically, `F`, the closure that we pass to execute in the new thread. It
116-
has two restrictions: It must be a `FnOnce` from `()` to `T`. Using `FnOnce`
117-
allows the closure to take ownership of any data it mentions from the parent
118-
thread. The other restriction is that `F` must be `Send`. We aren't allowed to
119-
transfer this ownership unless the type thinks that's okay.
120-
12188
Many languages have the ability to execute threads, but it's wildly unsafe.
12289
There are entire books about how to prevent errors that occur from shared
12390
mutable state. Rust helps out with its type system here as well, by preventing

src/librustdoc/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ struct Output {
130130

131131
pub fn main() {
132132
const STACK_SIZE: usize = 32000000; // 32MB
133-
let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || {
133+
let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
134134
let s = env::args().collect::<Vec<_>>();
135135
main_args(&s)
136-
}).unwrap().join();
136+
}).unwrap().join().unwrap();
137137
env::set_exit_status(res as i32);
138138
}
139139

src/libstd/thread/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
//! a join before any relevant stack frames are popped:
9494
//!
9595
//! ```rust
96+
//! # #![feature(scoped)]
9697
//! use std::thread;
9798
//!
9899
//! let guard = thread::scoped(move || {

src/test/bench/shootout-binarytrees.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ fn main() {
111111
let messages = (min_depth..max_depth + 1).step_by(2).map(|depth| {
112112
use std::num::Int;
113113
let iterations = 2.pow((max_depth - depth + min_depth) as u32);
114-
thread::scoped(move || inner(depth, iterations))
114+
thread::spawn(move || inner(depth, iterations))
115115
}).collect::<Vec<_>>();
116116

117117
for message in messages {
118-
println!("{}", message.join());
118+
println!("{}", message.join().unwrap());
119119
}
120120

121121
println!("long lived tree of depth {}\t check: {}",

src/test/bench/shootout-fannkuch-redux.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@ fn fannkuch(n: i32) -> (i32, i32) {
166166
for (_, j) in (0..N).zip((0..).step_by(k)) {
167167
let max = cmp::min(j+k, perm.max());
168168

169-
futures.push(thread::scoped(move|| {
169+
futures.push(thread::spawn(move|| {
170170
work(perm, j as usize, max as usize)
171171
}))
172172
}
173173

174174
let mut checksum = 0;
175175
let mut maxflips = 0;
176176
for fut in futures {
177-
let (cs, mf) = fut.join();
177+
let (cs, mf) = fut.join().unwrap();
178178
checksum += cs;
179179
maxflips = cmp::max(maxflips, mf);
180180
}

src/test/bench/shootout-k-nucleotide.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,17 +307,17 @@ fn main() {
307307

308308
let nb_freqs: Vec<_> = (1..3).map(|i| {
309309
let input = input.clone();
310-
(i, thread::scoped(move|| generate_frequencies(&input, i)))
310+
(i, thread::spawn(move|| generate_frequencies(&input, i)))
311311
}).collect();
312312
let occ_freqs: Vec<_> = OCCURRENCES.iter().map(|&occ| {
313313
let input = input.clone();
314-
thread::scoped(move|| generate_frequencies(&input, occ.len()))
314+
thread::spawn(move|| generate_frequencies(&input, occ.len()))
315315
}).collect();
316316

317317
for (i, freq) in nb_freqs {
318-
print_frequencies(&freq.join(), i);
318+
print_frequencies(&freq.join().unwrap(), i);
319319
}
320320
for (&occ, freq) in OCCURRENCES.iter().zip(occ_freqs.into_iter()) {
321-
print_occurrences(&mut freq.join(), occ);
321+
print_occurrences(&mut freq.join().unwrap(), occ);
322322
}
323323
}

src/test/bench/shootout-mandelbrot.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
8282
let mut precalc_i = Vec::with_capacity(h);
8383

8484
let precalc_futures = (0..WORKERS).map(|i| {
85-
thread::scoped(move|| {
85+
thread::spawn(move|| {
8686
let mut rs = Vec::with_capacity(w / WORKERS);
8787
let mut is = Vec::with_capacity(w / WORKERS);
8888

@@ -108,7 +108,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
108108
}).collect::<Vec<_>>();
109109

110110
for res in precalc_futures {
111-
let (rs, is) = res.join();
111+
let (rs, is) = res.join().unwrap();
112112
precalc_r.extend(rs.into_iter());
113113
precalc_i.extend(is.into_iter());
114114
}
@@ -123,7 +123,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
123123
let vec_init_r = arc_init_r.clone();
124124
let vec_init_i = arc_init_i.clone();
125125

126-
thread::scoped(move|| {
126+
thread::spawn(move|| {
127127
let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
128128
let init_r_slice = vec_init_r;
129129

@@ -144,7 +144,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
144144

145145
try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
146146
for res in data {
147-
try!(out.write(&res.join()));
147+
try!(out.write(&res.join().unwrap()));
148148
}
149149
out.flush()
150150
}

src/test/bench/shootout-reverse-complement.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
// ignore-android see #10393 #13206
4242

43-
#![feature(unboxed_closures, libc, old_io, collections, io, core)]
43+
#![feature(unboxed_closures, libc, old_io, collections, io, core, scoped)]
4444

4545
extern crate libc;
4646

src/test/bench/shootout-spectralnorm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
// no-pretty-expanded FIXME #15189
4242

4343
#![allow(non_snake_case)]
44-
#![feature(unboxed_closures, core, os)]
44+
#![feature(unboxed_closures, core, os, scoped)]
4545

4646
use std::iter::repeat;
4747
use std::thread;

0 commit comments

Comments
 (0)