
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.86] |
![]() |
|
Сообщ.
#1
,
|
|
|
Приветствую!
Решил скомпилировать тестовую программу "Обедающие философы" на языке Rust из мануала: ![]() ![]() use std::thread; use std::time::Duration; use std::sync::{Mutex, Arc}; 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(); thread::sleep(Duration::from_millis(150)); let _right = table.forks[self.right].lock().unwrap(); println!("{} начала есть.", self.name); thread::sleep(Duration::from_millis(1000)); println!("{} закончила есть.", self.name); } } 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("Джудит Батлер", 0, 1), Philosopher::new("Рая Дунаевская", 1, 2), Philosopher::new("Зарубина Наталья", 2, 3), Philosopher::new("Эмма Гольдман", 3, 4), Philosopher::new("Анна Шмидт", 0, 4), ]; let handles: Vec<_> = philosophers.into_iter().map(|p| { let table = table.clone(); thread::spawn(move || { p.eat(&table); }) }).collect(); for h in handles { h.join().unwrap(); } } Компилятор версии 1.25 под FreeBSD из портов. Все компилируется и запускается. Одна проблема - "философы" едят последовательно, а должны асинхронно. Что я делаю не так? Добавлено ЗЫ: Более того, этот же пример на https://play.rust-lang.org также работает неправильно. |
Сообщ.
#2
,
|
|
|
Убрал первую задержку в 150мс, "философы" начали обедать "правильно". Хм ...
![]() |
Сообщ.
#3
,
|
|
|
Вощем, на сколько я понял, реализация была сделана несколько топорно, а именно:
1) Времена "взятия вилок", "время еды" были константами - такого не бывает 2) Освобождение ресурса "вилка" предусмотрено не было По-сему, если бы последний философ "не был бы левшой", процесс бы вообще в большинстве случаев ловил бы дедлок. Ради интереса и обучения - постараюсь переделать. |
![]() |
Сообщ.
#4
,
|
|
Цитата JoeUser @ 2) Освобождение ресурса "вилка" предусмотрено не было Тут RAII используется. mutex.lock().unwrap() выдаёт нечто, что ты можешь использовать как объект, защищаемый мьютексом и что в drop-e (это полный аналог плюсовых деструкторов) вызовет unlock. |