summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exercises/20_threads/threads2.rs27
-rw-r--r--rustlings-macros/info.toml10
-rw-r--r--solutions/20_threads/threads2.rs42
3 files changed, 59 insertions, 20 deletions
diff --git a/exercises/20_threads/threads2.rs b/exercises/20_threads/threads2.rs
index 2bdeba9..7020cb9 100644
--- a/exercises/20_threads/threads2.rs
+++ b/exercises/20_threads/threads2.rs
@@ -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!());
}
diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml
index 37afa17..ab8c121 100644
--- a/rustlings-macros/info.toml
+++ b/rustlings-macros/info.toml
@@ -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]]
diff --git a/solutions/20_threads/threads2.rs b/solutions/20_threads/threads2.rs
index 4e18198..bc268d6 100644
--- a/solutions/20_threads/threads2.rs
+++ b/solutions/20_threads/threads2.rs
@@ -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);
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+}