Add a shared mutability between threads exercise

Closes #3. Thank you @jdm!!! ❇️
This commit is contained in:
Carol (Nichols || Goulding) 2015-09-29 14:39:25 -04:00
parent 8de7e3e072
commit 159330932a
2 changed files with 99 additions and 0 deletions

View File

@ -89,6 +89,12 @@ The [Error Handling](https://doc.rust-lang.org/stable/book/error-handling.html)
- ["result1.rs"](http://play.rust-lang.org/?code=%2F%2F+Make+this+test+pass%21+Scroll+down+for+hints+%3A%29%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Astruct+PositiveNonzeroInteger%28u64%29%3B%0A%0A%23%5Bderive%28PartialEq%2CDebug%29%5D%0Aenum+CreationError+%7B%0A++++Negative%2C%0A++++Zero%2C%0A%7D%0A%0Aimpl+PositiveNonzeroInteger+%7B%0A++++fn+new%28value%3A+i64%29+-%3E+Result%3CPositiveNonzeroInteger%2C+CreationError%3E+%7B%0A++++++++Ok%28PositiveNonzeroInteger%28value+as+u64%29%29%0A++++%7D%0A%7D%0A%0A%23%5Btest%5D%0Afn+test_creation%28%29+%7B%0A++++assert%21%28PositiveNonzeroInteger%3A%3Anew%2810%29.is_ok%28%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3ANegative%29%2C+PositiveNonzeroInteger%3A%3Anew%28-10%29%29%3B%0A++++assert_eq%21%28Err%28CreationError%3A%3AZero%29%2C+PositiveNonzeroInteger%3A%3Anew%280%29%29%3B%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+%60PositiveNonzeroInteger%3A%3Anew%60+is+always+creating+a+new+instance+and+returning+an+%60Ok%60+result.%0A%2F%2F+It+should+be+doing+some+checking%2C+returning+an+%60Err%60+result+if+those+checks+fail%2C+and+only%0A%2F%2F+returning+an+%60Ok%60+result+if+those+checks+determine+that+everything+is...+okay+%3A%29%0A)
### Threads
See [the Dining Philosophers example](https://doc.rust-lang.org/stable/book/dining-philosophers.html) and the [Concurrency Chapter](https://doc.rust-lang.org/stable/book/concurrency.html) from the book.
- ["threads1.rs"](http://play.rust-lang.org/?code=%2F%2F+Make+this+compile%21+Scroll+down+for+hints+%3A%29+The+idea+is+the+thread%0A%2F%2F+spawned+on+line+17+is+completing+jobs+while+the+main+thread+is%0A%2F%2F+monitoring+progress+until+10+jobs+are+completed.+If+you+see+6+lines%0A%2F%2F+of+%22waiting...%22+and+the+program+ends+without+timing+out+the+playground%2C%0A%2F%2F+you%27ve+got+it+%3A%29%0A%0Ause+std%3A%3Async%3A%3AArc%3B%0Ause+std%3A%3Athread%3B%0A%0Astruct+JobStatus+%7B%0A++++jobs_completed%3A+u32%2C%0A%7D%0A%0Afn+main%28%29+%7B%0A++++let+status+%3D+Arc%3A%3Anew%28JobStatus+%7B+jobs_completed%3A+0+%7D%29%3B%0A++++let+status_shared+%3D+status.clone%28%29%3B%0A++++thread%3A%3Aspawn%28move+%7C%7C+%7B%0A++++++++for+_+in+0..10+%7B%0A++++++++++++thread%3A%3Asleep_ms%28250%29%3B%0A++++++++++++status_shared.jobs_completed+%2B%3D+1%3B%0A++++++++%7D%0A++++%7D%29%3B%0A++++while+status.jobs_completed+%3C+10+%7B%0A++++++++println%21%28%22waiting...+%22%29%3B%0A++++++++thread%3A%3Asleep_ms%28500%29%3B%0A++++%7D%0A%7D%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+%60Arc%60+is+an+Atomic+Reference+Counted+pointer+that+allows+safe%2C+shared+access%0A%2F%2F+to+**immutable**+data.+But+we+want+to+*change*+the+number+of+%60jobs_completed%60%0A%2F%2F+so+we%27ll+need+to+also+use+another+type+that+will+only+allow+one+thread+to%0A%2F%2F+mutate+the+data+at+a+time.+Take+a+look+at+this+section+of+the+book%3A%0A%2F%2F+https%3A%2F%2Fdoc.rust-lang.org%2Fstable%2Fbook%2Fconcurrency.html%23safe-shared-mutable-state%0A%2F%2F+and+keep+scrolling+if+you%27d+like+more+hints+%3A%29%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Do+you+now+have+an+%60Arc%60+%60Mutex%60+%60JobStatus%60+at+the+beginning+of+main%3F+Like%3A%0A%2F%2F+%60let+status+%3D+Arc%3A%3Anew%28Mutex%3A%3Anew%28JobStatus+%7B+jobs_completed%3A+0+%7D%29%29%3B%60%0A%2F%2F+Similar+to+the+code+in+the+example+in+the+book+that+happens+after+the+text%0A%2F%2F+that+says+%22We+can+use+Arc%3CT%3E+to+fix+this.%22.+If+not%2C+give+that+a+try%21+If+you%0A%2F%2F+do+and+would+like+more+hints%2C+keep+scrolling%21%21%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%2F%2F+Make+sure+neither+of+your+threads+are+holding+onto+the+lock+of+the+mutex%0A%2F%2F+while+they+are+sleeping%2C+since+this+will+prevent+the+other+thread+from%0A%2F%2F+being+allowed+to+get+the+lock.+Locks+are+automatically+released+when%0A%2F%2F+they+go+out+of+scope.%0A%0A%2F%2F+Ok%2C+so%2C+real+talk%2C+this+was+actually+tricky+for+*me*+to+do+too.+And%0A%2F%2F+I+could+see+a+lot+of+different+problems+you+might+run+into%2C+so+at+this%0A%2F%2F+point+I%27m+not+sure+which+one+you%27ve+hit+%3A%29+Please+see+a+few+possible%0A%2F%2F+answers+on+https%3A%2F%2Fgithub.com%2Fcarols10cents%2Frustlings%2Fissues%2F3+--%0A%2F%2F+mine+is+a+little+more+complicated+because+I+decided+I+wanted+to+see%0A%2F%2F+the+number+of+jobs+currently+done+when+I+was+checking+the+status.%0A%0A%2F%2F+Please+open+an+issue+if+you%27re+still+running+into+a+problem+that%0A%2F%2F+these+hints+are+not+helping+you+with%2C+or+if+you%27ve+looked+at+the+sample%0A%2F%2F+answers+and+don%27t+understand+why+they+work+and+yours+doesn%27t.%0A%0A%2F%2F+If+you%27ve+learned+from+the+sample+solutions%2C+I+encourage+you+to+come%0A%2F%2F+back+to+this+exercise+and+try+it+again+in+a+few+days+to+reinforce%0A%2F%2F+what+you%27ve+learned+%3A%29%0A)
### Uncategorized
A few exercises based on things I've encountered or had trouble with getting used to.

93
threads/threads1.rs Normal file
View File

@ -0,0 +1,93 @@
// Make this compile! Scroll down for hints :) The idea is the thread
// spawned on line 17 is completing jobs while the main thread is
// monitoring progress until 10 jobs are completed. If you see 6 lines
// of "waiting..." and the program ends without timing out the playground,
// you've got it :)
use std::sync::Arc;
use std::thread;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(JobStatus { jobs_completed: 0 });
let status_shared = status.clone();
thread::spawn(move || {
for _ in 0..10 {
thread::sleep_ms(250);
status_shared.jobs_completed += 1;
}
});
while status.jobs_completed < 10 {
println!("waiting... ");
thread::sleep_ms(500);
}
}
// `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:
// https://doc.rust-lang.org/stable/book/concurrency.html#safe-shared-mutable-state
// and keep scrolling 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 }));`
// Similar to the code in the example in the book that happens after the text
// that says "We can use Arc<T> to fix this.". If not, give that a try! If you
// do and would like more hints, keep scrolling!!
// Make sure neither of your threads are holding onto the lock of the mutex
// while they are sleeping, since this will prevent the other thread from
// being allowed to get the lock. Locks are automatically released when
// 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 see a few possible
// answers on https://github.com/carols10cents/rustlings/issues/3 --
// mine is a little more complicated because I decided I wanted to see
// the number of jobs currently done when I was checking the status.
// 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
// back to this exercise and try it again in a few days to reinforce
// what you've learned :)