docs(exercises): Updated challenge instructions for threads1.rs #closes 287

I've seen from a cursory glance on the repo that a lot of people
struggle with this problem set because of the ambiguity in the
instructions (See issues #287, #743, #567).

I'd like to recommend perhaps putting a TODO on the lines that need
changing to stop people from falling down rabbit holes and pursuing
completely different solution to the exercise that avoids the core
pedagogical content of the problem, which is an understanding of
how Arc is an atomic reference counting primitive that relies on
.lock() and .unwrap() to solve shared state concurrency problems
with the Mutex primitive.

I've also added comments in the instructions to highlight why it is that
the solution is solved when the program prints the counter to the screen
6 times, as this was unclear and was distracting students from the core
takeaway of the exercise.
This commit is contained in:
richard jarram 2021-05-26 20:27:26 -07:00
parent a2f0401c4c
commit 3e6a8cfbdb

View file

@ -5,6 +5,12 @@
// spawned threads' sleep time, and the waiting threads sleep time, when you see 6 lines // spawned threads' sleep time, and the waiting threads sleep time, when you see 6 lines
// of "waiting..." and the program ends without timing out when running, // of "waiting..." and the program ends without timing out when running,
// you've got it :) // you've got it :)
// Why 6 lines, you ask? because the program will spawn one new thread that will increment
// the Jobstatus on 250ms intervals. At the same time, our original thread will check
// the Jobstatus at 500ms intervals. So, this count should be ~0 on the first iteration of
// the `while` loop; ~2 on the second iteration; ~4 on the third iteration; finally,
// ~10 on the sixth. Why? Because by the time our main thread peeks at the JobStatus counter,
// our second spawned thread will have already run two incremental operations on it.
// I AM NOT DONE // I AM NOT DONE
@ -17,14 +23,19 @@ struct JobStatus {
} }
fn main() { fn main() {
// TODO: Change the line below
let status = Arc::new(JobStatus { jobs_completed: 0 }); let status = Arc::new(JobStatus { jobs_completed: 0 });
let status_shared = status.clone(); let status_shared = status.clone();
// The code below spawns a single new thread that will run a for-loop code block 10 times.
thread::spawn(move || { thread::spawn(move || {
for _ in 0..10 { for _ in 0..10 {
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));
// TODO: change the line below
status_shared.jobs_completed += 1; status_shared.jobs_completed += 1;
} }
}); });
// The code below will check the count on JobStatus on 500ms intervals.
// TODO: Change the line below
while status.jobs_completed < 10 { while status.jobs_completed < 10 {
println!("waiting... "); println!("waiting... ");
thread::sleep(Duration::from_millis(500)); thread::sleep(Duration::from_millis(500));