programmieren-in-rust/aufgaben/sheet12/sol1/sleep-sort.rs

55 lines
1.8 KiB
Rust
Raw Normal View History

2017-02-16 15:34:22 +01:00
use std::thread;
use std::sync::{Arc, Mutex};
use std::time::Duration;
fn main() {
let mut arr = [83, 12, 13, 35, 91, 71, 75, 58, 26, 38, 2, 23, 10];
sleep_sort(&mut arr);
assert_eq!(arr, [2, 10, 12, 13, 23, 26, 35, 38, 58, 71, 75, 83, 91]);
}
fn sleep_sort(arr: &mut [u64]) {
let mut time_multiplier = 1.0;
let mut attempts = 0;
loop {
let result = Arc::new(Mutex::new(Vec::new()));
let mut handles = Vec::with_capacity(arr.len());
// Iterate over the immutable slice
for &thread_elem in arr.as_ref() {
// Create a new owner of the Arc to move into the new thread
let result = result.clone();
handles.push(thread::spawn(move || {
let time = (thread_elem as f64 * time_multiplier) as u32;
thread::sleep(Duration::new(0, time));
result.lock().unwrap().push(thread_elem);
}));
}
// Make sure our main thread waits until all other threads are finished
for handle in handles {
handle.join().unwrap();
}
attempts += 1;
time_multiplier *= 2.0;
// Now, there should be only one owner of the Arc left: this main
// thread. Thus we can unwrap it to get the ownership of the vector.
let result = Arc::try_unwrap(result).unwrap().into_inner().unwrap();
// If the resulting vector is actually sorted, we can write all
// elements to the original slice.
if result.iter().zip(&result[1..]).all(|(&a, &b)| a <= b) {
for (orig, new) in arr.iter_mut().zip(result) {
*orig = new;
}
break;
}
}
println!("Sorted in {} attempts (multiplier: {})", attempts, time_multiplier);
}