mirror of
https://github.com/notohh/rustlings.git
synced 2024-11-22 22:02:22 -05:00
feat: Adding threads1.rs with a focus on JoinHandles and waiting for
spawned threads to finish. Moved the original threads1.rs to threads2.rs with the focus on the Mutex and modifying shared data. #892
This commit is contained in:
parent
20024d40c5
commit
b4f52cb937
3 changed files with 69 additions and 28 deletions
|
@ -1,32 +1,31 @@
|
||||||
// threads1.rs
|
// threads1.rs
|
||||||
// Make this compile! Execute `rustlings hint threads1` for hints :)
|
// Make this compile and run! Execute 'rustlings hint threads1' for hints :)
|
||||||
// The idea is the thread spawned on line 22 is completing jobs while the main thread is
|
// This program should wait until all the spawned threads have finished before exiting.
|
||||||
// monitoring progress until 10 jobs are completed. Because of the difference between the
|
|
||||||
// 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,
|
|
||||||
// you've got it :)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
struct JobStatus {
|
|
||||||
jobs_completed: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let status = Arc::new(JobStatus { jobs_completed: 0 });
|
|
||||||
let status_shared = status.clone();
|
let mut handles = vec![];
|
||||||
thread::spawn(move || {
|
for i in 0..10 {
|
||||||
for _ in 0..10 {
|
thread::spawn(move || {
|
||||||
thread::sleep(Duration::from_millis(250));
|
thread::sleep(Duration::from_millis(250));
|
||||||
status_shared.jobs_completed += 1;
|
println!("thread {} is complete", i);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
while status.jobs_completed < 10 {
|
|
||||||
println!("waiting... ");
|
|
||||||
thread::sleep(Duration::from_millis(500));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut completed_threads = 0;
|
||||||
|
for handle in handles {
|
||||||
|
// TODO: a struct is returned from thread::spawn, can you use it?
|
||||||
|
completed_threads += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if completed_threads != 10 {
|
||||||
|
panic!("Oh no! All the spawned threads did not finish!");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
34
exercises/threads/threads2.rs
Normal file
34
exercises/threads/threads2.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// threads2.rs
|
||||||
|
// Make this compile! Execute `rustlings hint threads2` for hints :)
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
struct JobStatus {
|
||||||
|
jobs_completed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let status = Arc::new(JobStatus { jobs_completed: 0 });
|
||||||
|
let mut handles = vec![];
|
||||||
|
for _ in 0..10 {
|
||||||
|
let status_shared = status.clone();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
handles.push(handle);
|
||||||
|
}
|
||||||
|
for handle in handles {
|
||||||
|
handle.join().unwrap();
|
||||||
|
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice anything
|
||||||
|
// interesting in the output? Do you have to 'join' on all the handles?
|
||||||
|
println!("jobs completed {}", ???);
|
||||||
|
}
|
||||||
|
}
|
24
info.toml
24
info.toml
|
@ -878,6 +878,22 @@ name = "threads1"
|
||||||
path = "exercises/threads/threads1.rs"
|
path = "exercises/threads/threads1.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
|
`JoinHandle` is a struct that is returned from a spawned thread:
|
||||||
|
https://doc.rust-lang.org/std/thread/fn.spawn.html
|
||||||
|
|
||||||
|
A challenge with multi-threaded applications is that the main thread can
|
||||||
|
finish before the spawned threads are completed.
|
||||||
|
https://doc.rust-lang.org/book/ch16-01-threads.html#waiting-for-all-threads-to-finish-using-join-handle
|
||||||
|
|
||||||
|
Collect the JoinHandles and wait for them to finish.
|
||||||
|
https://doc.rust-lang.org/std/thread/struct.JoinHandle.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "threads2"
|
||||||
|
path = "exercises/threads/threads2.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
`Arc` is an Atomic Reference Counted pointer that allows safe, shared access
|
`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`
|
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
|
so we'll need to also use another type that will only allow one thread to
|
||||||
|
@ -898,14 +914,6 @@ while they are sleeping, since this will prevent the other thread from
|
||||||
being allowed to get the lock. Locks are automatically released when
|
being allowed to get the lock. Locks are automatically released when
|
||||||
they go out of scope.
|
they go out of scope.
|
||||||
|
|
||||||
Ok, so, real talk, this was actually tricky for *me* to do too. And
|
|
||||||
I could see a lot of different problems you might run into, so at this
|
|
||||||
point I'm not sure which one you've hit :)
|
|
||||||
|
|
||||||
Please open an issue if you're still running into a problem that
|
|
||||||
these hints are not helping you with, or if you've looked at the sample
|
|
||||||
answers and don't understand why they work and yours doesn't.
|
|
||||||
|
|
||||||
If you've learned from the sample solutions, I encourage you to come
|
If you've learned from the sample solutions, I encourage you to come
|
||||||
back to this exercise and try it again in a few days to reinforce
|
back to this exercise and try it again in a few days to reinforce
|
||||||
what you've learned :)"""
|
what you've learned :)"""
|
||||||
|
|
Loading…
Reference in a new issue