В книге Язык программирования Rust в главе 4.3 Обедающие философы в Arch Linux на ядре 4.10.3-1-ARCH выполнение кода, скомпилированного в rustc 1.16.0
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();
}
}
даёт результат
Эмма Гольдман начала есть.
Эмма Гольдман закончила есть.
Зарубина Наталья начала есть.
Зарубина Наталья закончила есть.
Рая Дунаевская начала есть.
Рая Дунаевская закончила есть.
Джудит Батлер начала есть.
Джудит Батлер закончила есть.
Анна Шмидт начала есть.
Анна Шмидт закончила есть.
вместо
Рая Дунаевская начала есть.
Эмма Гольдман начала есть.
Эмма Гольдман закончила есть.
Рая Дунаевская закончила есть.
Джудит Батлер начала есть.
Зарубина Наталья начала есть.
Джудит Батлер закончила есть.
Анна Шмидт начала есть.
Зарубина Наталья закончила есть.
Анна Шмидт закончила есть.
Ожидаемого параллелизма не наблюдается. В чём может быть проблема?