Skip to content

Commit 15cf9e6

Browse files
committed
wip
1 parent d27a61e commit 15cf9e6

12 files changed

+156
-5
lines changed

index-template.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<html>
2+
<body>
3+
<h2>Rust concurrency tutorial</h2>
4+
<ol>
5+
<li> <a href="src/hello_world.rs">Hello World</a>
6+
<ul>
7+
<li>Goal: make it greet you by name
8+
<li>Time: 3 minutes
9+
</ul>
10+
<li> <a href="src/borrowing.rs">Borrowing</a>
11+
<ul>
12+
<li>Goal: convert this code to use borrowing
13+
instead so that it compiles
14+
<li>Time: 3 minutes
15+
</ul>
16+
<li> <a href="src/sequential_search.rs">Sequential search</a>
17+
<ul>
18+
<li>Goal: implement <code>find_best_store</code>
19+
<li>Time: 10 minutes
20+
</ul>
21+
<li> <a href="src/parallel_search.rs">Parallel search</a>:
22+
<ul>
23+
<li>Goal: make this actually run in parallel
24+
<li>Extra bonus: avoid cloning the store name
25+
<li>Time: 10 minutes
26+
</ul>
27+
<li> <a href="src/shared_memory.rs">Shared memory </a>:
28+
<ul>
29+
<li>Goal: Adapt your previous code to use `Arc`
30+
<li>Extra bonus: How can you minimize cloning the underlying shopping list?
31+
<li>Time: 10 minutes
32+
</ul>
33+
<li> <a href="src/mutex.rs">Introduce Mutex</a>:
34+
<ul>
35+
<li>Goal: Adapt your previous code to introduce a mutex
36+
and use it to find the best price
37+
<li>Time: 10 minutes
38+
</ul>
39+
</ol>
40+
</body>
41+
</html>
File renamed without changes.

src/borrowing.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub fn main() {
2+
let mut name = format!("fellow ");
3+
name.push_str("Rustacean");
4+
helper(name);
5+
helper(name);
6+
}
7+
8+
fn helper(name: String) {
9+
println!("Hello, {}!", name);
10+
}

src/channels.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#![allow(dead_code)]
2+
3+
use std::collections::HashMap;
4+
use std::f32::INFINITY;
5+
use std::sync::mpsc::channel;
6+
use std::thread;
7+
8+
struct Store {
9+
name: String,
10+
prices: HashMap<String, f32>,
11+
}
12+
13+
impl Store {
14+
fn new(name: String) -> Store {
15+
Store {
16+
name: name,
17+
prices: HashMap::new(),
18+
}
19+
}
20+
21+
fn add_item(&mut self, name: String, price: f32) {
22+
self.prices.insert(name, price);
23+
}
24+
25+
fn price(&self, item_name: &str) -> f32 {
26+
self.prices[item_name]
27+
}
28+
}
29+
30+
fn build_stores() -> Vec<Store> {
31+
let mut stores = vec![];
32+
33+
let mut store = Store::new(format!("R-mart"));
34+
store.add_item(format!("chocolate"), 5.0);
35+
store.add_item(format!("doll"), 22.0);
36+
store.add_item(format!("bike"), 150.0);
37+
stores.push(store);
38+
39+
let mut store = Store::new(format!("Bullseye"));
40+
store.add_item(format!("chocolate"), 2.0);
41+
store.add_item(format!("doll"), 23.0);
42+
store.add_item(format!("bike"), 145.0);
43+
stores.push(store);
44+
45+
let mut store = Store::new(format!("Woolmart"));
46+
store.add_item(format!("chocolate"), 2.0);
47+
store.add_item(format!("doll"), 23.0);
48+
store.add_item(format!("bike"), 146.0);
49+
stores.push(store);
50+
51+
stores
52+
}
53+
54+
fn find_best_store(stores: Vec<Store>, shopping_list: &Vec<String>) -> String {
55+
assert!(stores.len() > 0);
56+
57+
// TODO:
58+
// - create channel for receiving message
59+
// - start threads for each store, giving each a `tx` to send messages to
60+
// - have each thread send its name and sum
61+
// - find and return best name
62+
63+
for store in stores {
64+
let shopping_list = shopping_list.clone();
65+
thread::spawn(move || {
66+
let sum = compute_sum(&store, &shopping_list);
67+
unimplemented!("send sum to some channel");
68+
});
69+
}
70+
71+
let mut best = None;
72+
let mut best_price = INFINITY;
73+
while true { // <-- change to some suitable loop!
74+
let (sum, name) = unimplemented!();
75+
if sum < best_price {
76+
best = Some(name);
77+
best_price = sum;
78+
}
79+
}
80+
81+
best.unwrap() // there will always be at least one store
82+
}
83+
84+
fn compute_sum(store: &Store, shopping_list: &Vec<String>) -> f32 {
85+
shopping_list.iter()
86+
.map(|item_name| store.price(item_name))
87+
.fold(0.0, |v, u| v + u)
88+
}
89+
90+
pub fn main() {
91+
let shopping_list = vec![format!("chocolate"),
92+
format!("doll"),
93+
format!("bike")];
94+
let stores = build_stores();
95+
let best_store = find_best_store(stores, &shopping_list);
96+
println!("Best store: {}", best_store);
97+
}
98+

src/example_port.rs renamed to src/channels_sol.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use std::collections::HashMap;
44
use std::f32::INFINITY;
5+
use std::mem;
56
use std::sync::mpsc::channel;
67
use std::thread;
78

@@ -55,7 +56,6 @@ fn find_best_store(stores: Vec<Store>, shopping_list: &Vec<String>) -> String {
5556
assert!(stores.len() > 0);
5657

5758
let (tx, rx) = channel();
58-
let count = stores.len();
5959
for store in stores {
6060
let shopping_list = shopping_list.clone();
6161
let tx = tx.clone();
@@ -64,11 +64,11 @@ fn find_best_store(stores: Vec<Store>, shopping_list: &Vec<String>) -> String {
6464
tx.send((sum, store.name)).unwrap();
6565
});
6666
}
67+
mem::drop(tx);
6768

6869
let mut best = None;
6970
let mut best_price = INFINITY;
70-
for _ in 0 .. count {
71-
let (sum, name) = rx.recv().unwrap();
71+
for (sum, name) in rx {
7272
if sum < best_price {
7373
best = Some(name);
7474
best_price = sum;
File renamed without changes.

src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ mod example03;
55
mod example_sequential_search;
66
mod example_parallel_search;
77
mod example_parallel_search_sol;
8-
mod example_port;
8+
mod example_channels;
9+
mod example_channels_sol;
910
mod example_actor;
1011
mod example_shared_memory;
1112
mod example_mutex;
@@ -31,7 +32,8 @@ fn main() {
3132
example_parallel_search_sol::main();
3233

3334
println!("----------------------------------------------------------------------");
34-
example_port::main();
35+
// example_channels::main(); // not expected to execute
36+
example_channels_sol::main();
3537

3638
println!("----------------------------------------------------------------------");
3739
example_actor::main();
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)