Skip to content

Commit 02a877c

Browse files
committed
Change story of exercise async1
- Remove confusing use of atomics. Use return values of async tasks instead, to ensure all tasks are awaited. - Remove use of `println!()`, which uses a global lock and cannot be executed in parallel.
1 parent 229ca5a commit 02a877c

2 files changed

Lines changed: 55 additions & 79 deletions

File tree

exercises/24_async/async1.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
// Tim has to complete a few chores today, before he's allowed to play soccer
2-
// with his friends. His friends decide to help him. Working together, they
3-
// finish the chores earlier and have more time left to play soccer.
1+
// Alice is an elementary school teacher who needs to calculate the mean test
2+
// score for three classes she teaches. Instead of calculating them one after
3+
// the other, she decides to ask her friends Bob and Catherine for help. Working
4+
// together, they can finish the job much faster.
45
//
5-
// Let's simulate this using asynchronous programming. Each boy is represented
6-
// as an asynchronous task, which can be executed concurrently (they can be
7-
// working at the same time).
8-
9-
use std::sync::atomic::{AtomicU8, Ordering};
10-
11-
// Used by "mom" to check that all chores are done before Tim plays soccer :-)
12-
static CHORES_DONE: AtomicU8 = AtomicU8::new(0);
6+
// Let's simulate this using asynchronous programming. Each person is
7+
// represented as an asynchronous task, which can be executed concurrently (i.e.
8+
// they can be doing the calculations at the same time).
139

1410
fn main() {
1511
// Async tasks need to be executed by a "runtime", which is not provided by
@@ -18,38 +14,29 @@ fn main() {
1814
.build()
1915
.unwrap();
2016

21-
// TODO: Fix the compiler errors by making the spawned function async.
22-
let task_tim = rt.spawn(tim());
23-
let task_carl = rt.spawn(carl());
24-
let task_nick = rt.spawn(nick());
17+
let scores_class_a = &[83, 77, 92];
18+
let scores_class_b = &[84, 88, 96];
19+
let scores_class_c = &[71, 83, 76];
2520

26-
// Block the runtime on a task that waits for all boys to finish the chores.
27-
// TODO: "await" all three tasks to fix the compiler errors.
28-
rt.block_on(async {
29-
task_tim;
30-
task_carl;
31-
task_nick;
21+
// TODO: Fix the compiler errors by making the spawned function async.
22+
let alice = rt.spawn(calculate_mean_score(scores_class_a));
23+
let bob = rt.spawn(calculate_mean_score(scores_class_b));
24+
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
25+
26+
// Block the runtime on a task that awaits all three calculations.
27+
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
28+
[
29+
// TODO: "await" all three tasks to fix the compiler error.
30+
alice, bob, catherine,
31+
]
3232
});
3333

34-
assert_eq!(
35-
CHORES_DONE.load(Ordering::SeqCst),
36-
3,
37-
"Did you (a)wait for all the boys to finish the chores?"
38-
);
39-
println!("Ready to play soccer!");
40-
}
41-
42-
fn tim() {
43-
println!("Cleaning my room...");
44-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
45-
}
46-
47-
fn carl() {
48-
println!("Washing the dishes...");
49-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
34+
assert_eq!(mean_score_a, 84);
35+
assert_eq!(mean_score_b, 89);
36+
assert_eq!(mean_score_c, 76);
5037
}
5138

52-
fn nick() {
53-
println!("Mowing the lawn...");
54-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
39+
fn calculate_mean_score(score_list: &[usize]) -> usize {
40+
let score_sum: usize = score_list.iter().sum();
41+
score_sum / score_list.len()
5542
}

solutions/24_async/async1.rs

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
// Tim has to complete a few chores today, before he's allowed to play soccer
2-
// with his friends. His friends decide to help him. Working together, they
3-
// finish the chores earlier and have more time left to play soccer.
1+
// Alice is an elementary school teacher who needs to calculate the mean test
2+
// score for three classes she teaches. Instead of calculating them one after
3+
// the other, she decides to ask her friends Bob and Catherine for help. Working
4+
// together, they can finish the job much faster.
45
//
5-
// Let's simulate this using asynchronous programming. Each boy is represented
6-
// as an asynchronous task, which can be executed concurrently (they can be
7-
// working at the same time).
8-
9-
use std::sync::atomic::{AtomicU8, Ordering};
10-
11-
// Used by "mom" to check that all chores are done before Tim plays soccer :-)
12-
static CHORES_DONE: AtomicU8 = AtomicU8::new(0);
6+
// Let's simulate this using asynchronous programming. Each person is
7+
// represented as an asynchronous task, which can be executed concurrently (i.e.
8+
// they can be doing the calculations at the same time).
139

1410
fn main() {
1511
// Async tasks need to be executed by a "runtime", which is not provided by
@@ -18,36 +14,29 @@ fn main() {
1814
.build()
1915
.unwrap();
2016

21-
let task_tim = rt.spawn(tim());
22-
let task_carl = rt.spawn(carl());
23-
let task_nick = rt.spawn(nick());
24-
25-
// Block the runtime on a task that waits for all boys to finish the chores.
26-
rt.block_on(async {
27-
task_tim.await.unwrap();
28-
task_carl.await.unwrap();
29-
task_nick.await.unwrap();
17+
let scores_class_a = &[83, 77, 92];
18+
let scores_class_b = &[84, 88, 96];
19+
let scores_class_c = &[71, 83, 76];
20+
21+
let alice = rt.spawn(calculate_mean_score(scores_class_a));
22+
let bob = rt.spawn(calculate_mean_score(scores_class_b));
23+
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
24+
25+
// Block the runtime on a task that awaits all three calculations.
26+
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
27+
[
28+
alice.await.unwrap(),
29+
bob.await.unwrap(),
30+
catherine.await.unwrap(),
31+
]
3032
});
3133

32-
assert_eq!(
33-
CHORES_DONE.load(Ordering::SeqCst),
34-
3,
35-
"Did you (a)wait for all the boys to finish the chores?"
36-
);
37-
println!("Ready to play soccer!");
38-
}
39-
40-
async fn tim() {
41-
println!("Cleaning my room...");
42-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
43-
}
44-
45-
async fn carl() {
46-
println!("Washing the dishes...");
47-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
34+
assert_eq!(mean_score_a, 84);
35+
assert_eq!(mean_score_b, 89);
36+
assert_eq!(mean_score_c, 76);
4837
}
4938

50-
async fn nick() {
51-
println!("Mowing the lawn...");
52-
CHORES_DONE.fetch_add(1, Ordering::SeqCst);
39+
async fn calculate_mean_score(score_list: &[usize]) -> usize {
40+
let score_sum: usize = score_list.iter().sum();
41+
score_sum / score_list.len()
5342
}

0 commit comments

Comments
 (0)