forked from GabrielLacerda00/ProjetoConcorrente
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemaforo.rs
65 lines (52 loc) · 1.62 KB
/
semaforo.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::sync::{Arc, Barrier};
use std::thread;
const N: usize = 1024; // número de threads
struct Bakery {
choosing: [bool; N],
ticket: [usize; N],
}
impl Bakery {
fn new() -> Self {
Bakery {
choosing: [false; N],
ticket: [0; N],
}
}
fn max(arr: [usize; N]) -> usize {
*arr.iter().max().unwrap()
}
fn lock(&mut self, id: usize) {
self.choosing[id] = true;
self.ticket[id] = Self::max(self.ticket) + 1;
self.choosing[id] = false;
for j in 0..N {
while self.choosing[j] {} // Espera se j está escolhendo
while self.ticket[j] != 0 && (self.ticket[j] < self.ticket[id] || (self.ticket[j] == self.ticket[id] && j < id)) {}
// Espera se j tem um ticket menor ou tem o mesmo ticket mas um ID menor
}
}
fn unlock(&mut self, id: usize) {
self.ticket[id] = 0;
}
}
fn main() {
let bakery = Arc::new(std::sync::Mutex::new(Bakery::new()));
let barrier = Arc::new(Barrier::new(N));
let handles: Vec<_> = (0..N).map(|i| {
let bakery = Arc::clone(&bakery);
let barrier = Arc::clone(&barrier);
thread::spawn(move || {
barrier.wait(); // Espera até que todas as threads estejam prontas
for _ in 0..1000 {
let mut bakery = bakery.lock().unwrap();
bakery.lock(i);
// região crítica vazia
bakery.unlock(i);
}
})
}).collect();
for handle in handles {
handle.join().unwrap();
}
println!("Todas as threads completaram.");
}