threads2 solution

This commit is contained in:
mo8it 2024-07-01 11:11:11 +02:00
parent b000164eed
commit dfa2b44f71
3 changed files with 59 additions and 20 deletions

View file

@ -1,35 +1,34 @@
// Building on the last exercise, we want all of the threads to complete their
// work but this time the spawned threads need to be in charge of updating a
// shared value: JobStatus.jobs_completed
// work. But this time, the spawned threads need to be in charge of updating a
// shared value: `JobStatus.jobs_done`
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::{sync::Arc, thread, time::Duration};
struct JobStatus {
jobs_completed: u32,
jobs_done: u32,
}
fn main() {
// TODO: `Arc` isn't enough if you want a **mutable** shared state
let status = Arc::new(JobStatus { jobs_completed: 0 });
// TODO: `Arc` isn't enough if you want a **mutable** shared state.
let status = Arc::new(JobStatus { jobs_done: 0 });
let mut handles = vec![];
let mut handles = Vec::new();
for _ in 0..10 {
let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value
status_shared.jobs_completed += 1;
// TODO: You must take an action before you update a shared value.
status_shared.jobs_done += 1;
});
handles.push(handle);
}
// Waiting for all jobs to complete
// Waiting for all jobs to complete.
for handle in handles {
handle.join().unwrap();
}
// TODO: Print the value of `JobStatus.jobs_completed`
println!("Jobs completed: {}", ???);
// TODO: Print the value of `JobStatus.jobs_done`.
println!("Jobs done: {}", todo!());
}

View file

@ -1051,19 +1051,19 @@ dir = "20_threads"
test = false
hint = """
`Arc` is an Atomic Reference Counted pointer that allows safe, shared access
to **immutable** data. But we want to *change* the number of `jobs_completed`
so we'll need to also use another type that will only allow one thread to
mutate the data at a time. Take a look at this section of the book:
to **immutable** data. But we want to *change* the number of `jobs_done` so
we'll need to also use another type that will only allow one thread to mutate
the data at a time. Take a look at this section of the book:
https://doc.rust-lang.org/book/ch16-03-shared-state.html#atomic-reference-counting-with-arct
Keep reading if you'd like more hints :)
Do you now have an `Arc<Mutex<JobStatus>>` at the beginning of `main`? Like:
```
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let status = Arc::new(Mutex::new(JobStatus { jobs_done: 0 }));
```
Similar to the code in the following example in the book:
Similar to the code in the following example in The Book:
https://doc.rust-lang.org/book/ch16-03-shared-state.html#sharing-a-mutext-between-multiple-threads"""
[[exercises]]

View file

@ -1 +1,41 @@
// Solutions will be available before the stable release. Thank you for testing the beta version 🥰
// Building on the last exercise, we want all of the threads to complete their
// work. But this time, the spawned threads need to be in charge of updating a
// shared value: `JobStatus.jobs_done`
use std::{
sync::{Arc, Mutex},
thread,
time::Duration,
};
struct JobStatus {
jobs_done: u32,
}
fn main() {
// `Arc` isn't enough if you want a **mutable** shared state.
// We need to wrap the value with a `Mutex`.
let status = Arc::new(Mutex::new(JobStatus { jobs_done: 0 }));
// ^^^^^^^^^^^ ^
let mut handles = Vec::new();
for _ in 0..10 {
let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
// Lock before you update a shared value.
status_shared.lock().unwrap().jobs_done += 1;
// ^^^^^^^^^^^^^^^^
});
handles.push(handle);
}
// Waiting for all jobs to complete.
for handle in handles {
handle.join().unwrap();
}
println!("Jobs done: {}", status.lock().unwrap().jobs_done);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}