Skip to content

Commit a3e1038

Browse files
committed
threads: Add the no mspc channel account exercice
Signed-off-by: Samuel Ortiz <[email protected]>
1 parent 11ffe64 commit a3e1038

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

threads/account-no-channel/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

threads/account-no-channel/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "account-no-channel"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use std::sync::Arc;
2+
use std::sync::Mutex;
3+
use std::thread;
4+
use std::time::Duration;
5+
6+
#[derive(Clone, Debug, Default)]
7+
struct Account {
8+
transactions: Vec<i32>,
9+
balance: i32,
10+
}
11+
12+
impl Account {
13+
fn new() -> Self {
14+
Account {
15+
balance: 0,
16+
..Default::default()
17+
}
18+
}
19+
20+
fn withdrawal(&mut self, request: u32) -> u32 {
21+
if self.balance <= 0 {
22+
return 0;
23+
}
24+
25+
let balance = self.balance as u32;
26+
let withdrawal = if balance <= request {
27+
self.balance
28+
} else {
29+
request as i32
30+
};
31+
32+
self.transactions.push(-withdrawal);
33+
self.balance -= withdrawal;
34+
35+
withdrawal as u32
36+
}
37+
38+
fn deposit(&mut self, deposit: i32) {
39+
self.transactions.push(deposit);
40+
self.balance += deposit;
41+
}
42+
43+
fn balance(&self) -> i32 {
44+
self.balance
45+
}
46+
}
47+
48+
const GRAND_TOTAL: u32 = 400;
49+
50+
fn main() {
51+
let account = Arc::new(Mutex::new(Account::new()));
52+
53+
let child_account = Arc::clone(&account);
54+
let parent_account = Arc::clone(&account);
55+
let banker_account = Arc::clone(&account);
56+
57+
let child_thread = thread::spawn(move || {
58+
let mut total_withdrawal = 0;
59+
60+
loop {
61+
thread::sleep(Duration::from_millis(1500));
62+
let mut locked_account = child_account.lock().unwrap();
63+
let withdrawal = locked_account.withdrawal(50);
64+
total_withdrawal += withdrawal;
65+
println!("CHILD <- {}", withdrawal);
66+
67+
if total_withdrawal >= GRAND_TOTAL {
68+
break;
69+
}
70+
}
71+
});
72+
73+
let parent_thread = thread::spawn(move || {
74+
let mut total_deposit = 0;
75+
76+
loop {
77+
thread::sleep(Duration::from_secs(5));
78+
let mut locked_account = parent_account.lock().unwrap();
79+
80+
locked_account.deposit(80);
81+
println!("PARENT -> {}", 80);
82+
total_deposit += 80;
83+
84+
if total_deposit >= GRAND_TOTAL {
85+
break;
86+
}
87+
}
88+
});
89+
90+
// Monitoring thread
91+
thread::spawn(move || loop {
92+
thread::sleep(Duration::from_millis(500));
93+
let locked_account = banker_account.lock().unwrap();
94+
println!("** Balance {} **", locked_account.balance());
95+
});
96+
97+
child_thread.join().unwrap();
98+
parent_thread.join().unwrap();
99+
100+
println!("Account {:?}", account);
101+
}

0 commit comments

Comments
 (0)