Merge 02a877c00cb0ce5cdf2cf85f696f81f48a294dfc into db3f3325072b9cf8b49499f9da86c48bc716a043

This commit is contained in:
Remo Senekowitsch 2026-05-17 01:52:39 +02:00 committed by GitHub
commit 423a98e5d7
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 = "conversions4_sol", path = "../solutions/23_conversions/conversions4.rs" },
{ name = "conversions5", path = "../exercises/23_conversions/conversions5.rs" },
{ name = "conversions5_sol", path = "../solutions/23_conversions/conversions5.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

@ -1211,3 +1211,17 @@ name = "conversions5"
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()
}