Closed vincentbernat closed 9 years ago
The output is nondeterministic, so it depends on your system.
Are you on a multicore system? Last time I heard of someone getting sequential output, they were in a VM with only one core....
If we do the timeline of the original events, we get:
Gilles Deleuze is eating.
(1 whole second)
Gilles Deleuze is done eating.
Friedrich Nietzsche is eating.
(1 whole second)
Friedrich Nietzsche is done eating.
Michel Foucault is eating.
Baruch Spinoza is eating.
(1 whole second)
Baruch Spinoza is done eating.
Karl Marx is eating.
(1 whole second)
Karl Marx is done eating.
Michel Foucault is done eating.
So, the initial example takes at least 4 seconds to execute. I am talking about the example without the forks. Unless the threads are cooperative (and thread::sleep_ms
isn't yielding which would be odd), this is quite improbable to find a system where Karl Marx is eating after at least 3 seconds. Also, if the threads were cooperative Michel Foucault and Baruch Spinoza should not eat together.
I think that the output was generated at a time where there was no thread::sleep_ms
call.
Are you sure you have the exact same code? There's a possibility you're actually joining sequentially....
I am talking about this code (unfortunately, I don't know how to point to a line number in a markdown document):
use std::thread;
struct Philosopher {
name: String,
}
impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}
fn eat(&self) {
println!("{} is eating.", self.name);
thread::sleep_ms(1000);
println!("{} is done eating.", self.name);
}
}
fn main() {
let philosophers = vec![
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];
let handles: Vec<_> = philosophers.into_iter().map(|p| {
thread::spawn(move || {
p.eat();
})
}).collect();
for h in handles {
h.join().unwrap();
}
}
So, yes, join is done sequentially, but join is just about waiting for threads to end. All threads should (and they do) execute in parallel. The output should be 5 lines of philosophers starting to eat and 5 lines of philosophers done eating. Any other output would show a flaw in threading.
Sorry, I did a poor job of articulating my concern here. It looks fine.
I am confused. Do you want me to do a PR or do you disagree?
It has been fixed in #26990. Closing.
The first output of the threaded example is:
And there is a remark about eating out of order. I would have expected an output like this instead:
(blank line has been added for clarity)