Merge 91fd773859d319f9c94afc160ee5e867a70755e8 into 1d53bd1b54cf8ccf7638862be43d9ae2c964c9ea

This commit is contained in:
Remo Senekowitsch 2026-05-09 10:31:12 +02:00 committed by GitHub
commit 5cc1983752
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 116 additions and 0 deletions

View File

@ -188,6 +188,8 @@ bin = [
{ name = "try_from_into_sol", path = "../solutions/23_conversions/try_from_into.rs" },
{ name = "as_ref_mut", path = "../exercises/23_conversions/as_ref_mut.rs" },
{ name = "as_ref_mut_sol", path = "../solutions/23_conversions/as_ref_mut.rs" },
{ name = "async1", path = "../exercises/24_async/async1.rs" },
{ name = "async1_sol", path = "../solutions/24_async/async1.rs" },
]
[package]
@ -196,6 +198,9 @@ edition = "2024"
# Don't publish the exercises on crates.io!
publish = false
[dependencies]
tokio = { version = "1", features = ["rt"] }
[profile.release]
panic = "abort"

View File

@ -0,0 +1,13 @@
# Async
Asynchronous programming is a model where tasks are delegated to a runtime that executes them concurrently.
It is particularly efficient for applications where many independent IO-operations are performed, e.g. web servers.
Rust provides the necessary primitives to do asynchronous programming in the language.
However, Rust's standard library does not include a runtime.
For these exercises, we will use the mainstream runtime called `tokio`.
## Further information
- [Fundamentals of Asynchronous Programming](https://doc.rust-lang.org/book/ch17-00-async-await.html)
- [Tokio documentation](https://docs.rs/tokio/latest/tokio/)

View File

@ -0,0 +1,42 @@
// Alice is an elementary school teacher who needs to calculate the mean test
// score for three classes she teaches. Instead of calculating them one after
// the other, she decides to ask her friends Bob and Catherine for help. Working
// together, they can finish the job much faster.
//
// Let's simulate this using asynchronous programming. Each person is
// represented as an asynchronous task, which can be executed concurrently (i.e.
// they can be doing the calculations at the same time).
fn main() {
// Async tasks need to be executed by a "runtime", which is not provided by
// Rust's standard library. Here, we use the mainstream runtime `tokio`.
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
let scores_class_a = &[83, 77, 92];
let scores_class_b = &[84, 88, 96];
let scores_class_c = &[71, 83, 76];
// TODO: Fix the compiler errors by making the spawned function async.
let alice = rt.spawn(calculate_mean_score(scores_class_a));
let bob = rt.spawn(calculate_mean_score(scores_class_b));
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
// Block the runtime on a task that awaits all three calculations.
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
[
// TODO: "await" all three tasks to fix the compiler error.
alice, bob, catherine,
]
});
assert_eq!(mean_score_a, 84);
assert_eq!(mean_score_b, 89);
assert_eq!(mean_score_c, 76);
}
fn calculate_mean_score(score_list: &[usize]) -> usize {
let score_sum: usize = score_list.iter().sum();
score_sum / score_list.len()
}

View File

@ -1199,3 +1199,17 @@ name = "as_ref_mut"
dir = "23_conversions"
hint = """
Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""
# ASYNC
[[exercises]]
name = "async1"
dir = "24_async"
test = false
hint = """
Asynchronous runtimes like tokio can only spawn tasks that are defined as async
functions, not regular ones. Add the "async" keyword before the "fn" keyword of
the functions "tim", "carl" and "nick".
An async task can wait for another one to complete by "awaiting" it. Add
".await" after the three "task_name" variables in the "block_on" call."""

View File

@ -0,0 +1,42 @@
// Alice is an elementary school teacher who needs to calculate the mean test
// score for three classes she teaches. Instead of calculating them one after
// the other, she decides to ask her friends Bob and Catherine for help. Working
// together, they can finish the job much faster.
//
// Let's simulate this using asynchronous programming. Each person is
// represented as an asynchronous task, which can be executed concurrently (i.e.
// they can be doing the calculations at the same time).
fn main() {
// Async tasks need to be executed by a "runtime", which is not provided by
// Rust's standard library. Here, we use the mainstream runtime `tokio`.
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
let scores_class_a = &[83, 77, 92];
let scores_class_b = &[84, 88, 96];
let scores_class_c = &[71, 83, 76];
let alice = rt.spawn(calculate_mean_score(scores_class_a));
let bob = rt.spawn(calculate_mean_score(scores_class_b));
let catherine = rt.spawn(calculate_mean_score(scores_class_c));
// Block the runtime on a task that awaits all three calculations.
let [mean_score_a, mean_score_b, mean_score_c]: [usize; _] = rt.block_on(async {
[
alice.await.unwrap(),
bob.await.unwrap(),
catherine.await.unwrap(),
]
});
assert_eq!(mean_score_a, 84);
assert_eq!(mean_score_b, 89);
assert_eq!(mean_score_c, 76);
}
async fn calculate_mean_score(score_list: &[usize]) -> usize {
let score_sum: usize = score_list.iter().sum();
score_sum / score_list.len()
}