use std::thread;
use std::sync::{Mutex,Arc};
#[derive(Debug)]
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:left,
right: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_ms(1000);
println!("{} is done eating",self.name);
}
}
#[derive(Debug)]
struct Table {
forks: Vec<Mutex<()>>,
}
fn main() {
let table = Arc::new(Table{
forks:vec![
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
]
});
let philosophers = vec![
Philosopher::new("Baruch Spinoza", 0, 1),
Philosopher::new("Gilles Deleuze", 1, 2),
Philosopher::new("Karl Marx", 2, 3),
Philosopher::new("Friedrich Nietzsche", 3, 4),
Philosopher::new("Michel Foucault", 0, 4),
];
let handles:Vec<_> = philosophers.into_iter().map(|p|{//philosophers 创建迭代器,拥有每个哲学家的所有权,map()接受一个闭包作为参数
let table = table.clone();//克隆table,引用技术加1
thread::spawn(move ||{//线程开始,传入哲学家所有权
p.eat(&table);
})
}).collect();//收集map结果,打包,赋值给handles
for h in handles{//遍历handles,
h.join().unwrap();//阻塞线程,确保主线程在所有线程结束之后退出
}
}
网友评论