Another thing to know about rust concurrency is that it supports safe "scoped" threads, or threads which have plain references to their parent threads stack.<p>This makes it very easy to write, for instance, a concurrent in-place quicksort (this example uses the scoped-pool crate, which provides a thread pool supporting scoped threads):<p><pre><code> extern crate scoped_pool; // scoped threads
extern crate itertools; // generic in-place partition
extern crate rand; // for choosing a random pivot
use rand::Rng;
use scoped_pool::{Pool, Scope};
pub fn quicksort<T: Send + Sync + Ord>(pool: &Pool, data: &mut [T]) {
pool.scoped(move |scoped| do_quicksort(scoped, data))
}
fn do_quicksort<'a, T: Send + Sync + Ord>(scope: &Scope<'a>, data: &'a mut [T]) {
scope.recurse(move |scope| {
if data.len() > 1 {
// Choose a random pivot.
let mut rng = rand::thread_rng();
let len = data.len();
let pivot_index = rng.gen_range(0, len); // Choose a random pivot
// Swap the pivot to the end.
data.swap(pivot_index, len - 1);
let split = {
// Retrieve the pivot.
let mut iter = data.into_iter();
let pivot = iter.next_back().unwrap();
// In-place partition the array.
itertools::partition(iter, |val| &*val <= &pivot)
};
// Swap the pivot back in at the split point by putting
// the element currently there are at the end of the slice.
data.swap(split, len - 1);
// Sort both halves (in-place!).
let (left, right) = data.split_at_mut(split);
do_quicksort(scope, left);
do_quicksort(scope, &mut right[1..]);
}
})
}
</code></pre>
In this example, quicksort will block until the array is fully sorted, then return.