Неправильные Rust-философы
    , тестовая программа работает не так как ожидалось
  ![]()  | 
Наши проекты:
 Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту  | 
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.5] | 
 
 | 
		
  | 
    Неправильные Rust-философы
    , тестовая программа работает не так как ожидалось
  | 
         
         
         
          
           Сообщ.
           #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.  |