diff --git a/crate/sync/Cargo.toml b/crate/sync/Cargo.toml new file mode 100644 index 0000000..2b9fa6f --- /dev/null +++ b/crate/sync/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ucore-sync" +version = "0.1.0" +authors = ["WangRunji "] + +[dependencies] diff --git a/crate/sync/src/main.rs b/crate/sync/src/main.rs new file mode 100644 index 0000000..49c86fa --- /dev/null +++ b/crate/sync/src/main.rs @@ -0,0 +1,7 @@ +mod mutex; +mod monitor; + +fn main() { +// mutex::main(); + monitor::main(); +} \ No newline at end of file diff --git a/crate/sync/src/monitor.rs b/crate/sync/src/monitor.rs new file mode 100644 index 0000000..2c7cb8d --- /dev/null +++ b/crate/sync/src/monitor.rs @@ -0,0 +1,82 @@ +use std::thread; +use std::sync::{Mutex, Condvar, Arc}; +use std::time::Duration; + +struct Philosopher { + name: String, + left: usize, + right: usize, +} + +impl Philosopher { + fn new(name: &str, left: usize, right: usize) -> Philosopher { + Philosopher { + name: name.to_string(), + left, + right, + } + } + + fn eat(&self, table: &Table) { + { + let mut fork_status = table.fork_status.lock().unwrap(); + if fork_status[self.left] { + fork_status = table.fork_condvar[self.left].wait(fork_status).unwrap() + } + fork_status[self.left] = true; + if fork_status[self.right] { + fork_status = table.fork_condvar[self.right].wait(fork_status).unwrap() + } + fork_status[self.right] = true; + } + println!("{} is eating.", self.name); + thread::sleep(Duration::from_secs(1)); + { + let mut fork_status = table.fork_status.lock().unwrap(); + fork_status[self.left] = false; + fork_status[self.right] = false; + table.fork_condvar[self.left].notify_one(); + table.fork_condvar[self.right].notify_one(); + } + } + + fn think(&self) { + println!("{} is thinking.", self.name); + thread::sleep(Duration::from_secs(1)); + } +} + +struct Table { + fork_status: Mutex>, + fork_condvar: Vec, +} + +pub fn main() { + let table = Arc::new(Table { + fork_status: Mutex::new(vec![false; 5]), + fork_condvar: vec![Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new()], + }); + + let philosophers = vec![ + Philosopher::new("1", 0, 1), + Philosopher::new("2", 1, 2), + Philosopher::new("3", 2, 3), + Philosopher::new("4", 3, 4), + Philosopher::new("5", 0, 4), + ]; + + let handles: Vec<_> = philosophers.into_iter().map(|p| { + let table = table.clone(); + + thread::spawn(move || { + for _ in 0..5 { + p.think(); + p.eat(&table); + } + }) + }).collect(); + + for h in handles { + h.join().unwrap(); + } +} \ No newline at end of file diff --git a/crate/sync/src/mutex.rs b/crate/sync/src/mutex.rs new file mode 100644 index 0000000..06b3223 --- /dev/null +++ b/crate/sync/src/mutex.rs @@ -0,0 +1,71 @@ +use std::thread; +use std::sync::{Mutex, Arc}; +use std::time::Duration; + +struct Philosopher { + name: String, + left: usize, + right: usize, +} + +impl Philosopher { + fn new(name: &str, left: usize, right: usize) -> Philosopher { + Philosopher { + name: name.to_string(), + left, + right, + } + } + + fn eat(&self, table: &Table) { + let _left = table.forks[self.left].lock().unwrap(); + let _right = table.forks[self.right].lock().unwrap(); + + println!("{} is eating.", self.name); + thread::sleep(Duration::from_secs(1)); + } + + fn think(&self) { + println!("{} is thinking.", self.name); + thread::sleep(Duration::from_secs(1)); + } +} + +struct Table { + forks: Vec>, +} + +pub fn main() { + let table = Arc::new(Table { + forks: vec![ + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + ] + }); + + let philosophers = vec![ + Philosopher::new("1", 0, 1), + Philosopher::new("2", 1, 2), + Philosopher::new("3", 2, 3), + Philosopher::new("4", 3, 4), + Philosopher::new("5", 0, 4), + ]; + + let handles: Vec<_> = philosophers.into_iter().map(|p| { + let table = table.clone(); + + thread::spawn(move || { + for _ in 0..5 { + p.think(); + p.eat(&table); + } + }) + }).collect(); + + for h in handles { + h.join().unwrap(); + } +} \ No newline at end of file