@@ -43,22 +43,24 @@ in the core and standard libraries, which are still under development
43
43
and do not always present a consistent or complete interface.
44
44
45
45
For your reference, these are the standard modules involved in Rust
46
- concurrency at this writing.
46
+ concurrency at this writing:
47
47
48
- * [ ` 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 `
52
- * [ ` std::sync ` ] - More exotic synchronization tools, including locks
48
+ * [ ` 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 ` ,
52
+ * [ ` std::sync ` ] - More exotic synchronization tools, including locks,
53
53
* [ ` std::arc ` ] - The ARC (atomically reference counted) type,
54
- for safely sharing immutable data
54
+ for safely sharing immutable data,
55
+ * [ ` std::future ` ] - A type representing values that may be computed concurrently and retrieved at a later time.
55
56
56
57
[ `core::task` ] : core/task.html
57
58
[ `core::comm` ] : core/comm.html
58
59
[ `core::pipes` ] : core/pipes.html
59
60
[ `std::comm` ] : std/comm.html
60
61
[ `std::sync` ] : std/sync.html
61
62
[ `std::arc` ] : std/arc.html
63
+ [ `std::future` ] : std/future.html
62
64
63
65
# Basics
64
66
@@ -70,7 +72,7 @@ closure in the new task.
70
72
71
73
~~~~
72
74
# use core::io::println;
73
- use core::task::spawn;
75
+ # use core::task::spawn;
74
76
75
77
// Print something profound in a different task using a named function
76
78
fn print_message() { println("I am running in a different task!"); }
@@ -145,8 +147,8 @@ endpoint. Consider the following example of calculating two results
145
147
concurrently:
146
148
147
149
~~~~
148
- use core::task::spawn;
149
- use core::comm::{stream, Port, Chan};
150
+ # use core::task::spawn;
151
+ # use core::comm::{stream, Port, Chan};
150
152
151
153
let (port, chan): (Port<int>, Chan<int>) = stream();
152
154
@@ -233,7 +235,7 @@ Instead we can use a `SharedChan`, a type that allows a single
233
235
234
236
~~~
235
237
# use core::task::spawn;
236
- use core::comm::{stream, SharedChan};
238
+ # use core::comm::{stream, SharedChan};
237
239
238
240
let (port, chan) = stream();
239
241
let chan = SharedChan::new(chan);
@@ -282,6 +284,51 @@ let result = ports.foldl(0, |accum, port| *accum + port.recv() );
282
284
# fn some_expensive_computation(_i: uint) -> int { 42 }
283
285
~~~
284
286
287
+ ## Futures
288
+ With ` std::future ` , rust has a mechanism for requesting a computation and getting the result
289
+ later.
290
+
291
+ The basic example below illustrates this.
292
+ ~~~
293
+ # fn make_a_sandwich() {};
294
+ fn fib(n: uint) -> uint {
295
+ // lengthy computation returning an uint
296
+ 12586269025
297
+ }
298
+
299
+ let mut delayed_fib = std::future::spawn (|| fib(50) );
300
+ make_a_sandwich();
301
+ println(fmt!("fib(50) = %?", delayed_fib.get()))
302
+ ~~~
303
+
304
+ The call to ` future::spawn ` returns immediately a ` future ` object regardless of how long it
305
+ takes to run ` fib(50) ` . You can then make yourself a sandwich while the computation of ` fib ` is
306
+ running. The result of the execution of the method is obtained by calling ` get ` on the future.
307
+ This call will block until the value is available (* i.e.* the computation is complete). Note that
308
+ the future needs to be mutable so that it can save the result for next time ` get ` is called.
309
+
310
+ Here is another example showing how futures allow you to background computations. The workload will
311
+ be distributed on the available cores.
312
+ ~~~
313
+ fn partial_sum(start: uint) -> f64 {
314
+ let mut local_sum = 0f64;
315
+ for uint::range(start*100000, (start+1)*100000) |num| {
316
+ local_sum += (num as f64 + 1.0).pow(-2.0);
317
+ }
318
+ local_sum
319
+ }
320
+
321
+ fn main() {
322
+ let mut futures = vec::from_fn(1000, |ind| do std::future::spawn { partial_sum(ind) });
323
+
324
+ let mut final_res = 0f64;
325
+ for futures.each_mut |ft| {
326
+ final_res += ft.get();
327
+ }
328
+ println(fmt!("π^2/6 is not far from : %?", final_res));
329
+ }
330
+ ~~~
331
+
285
332
# Handling task failure
286
333
287
334
Rust has a built-in mechanism for raising exceptions. The ` fail!() ` macro
@@ -363,8 +410,8 @@ either task fails, it kills the other one.
363
410
~~~
364
411
# fn sleep_forever() { loop { task::yield() } }
365
412
# do task::try {
366
- do task:: spawn {
367
- do task:: spawn {
413
+ do spawn {
414
+ do spawn {
368
415
fail!(); // All three tasks will fail.
369
416
}
370
417
sleep_forever(); // Will get woken up by force, then fail
0 commit comments