I use random numbers quite a bit in parallel simulations that I'd like to be repeatable (seedable) regardless of threading, so for anyone that does need thread safety and doesn't want to pass around a RNG reference, here's an example of what I do:
#![feature(thread_local)]
extern crate rand;
extern crate xorshift;
use rand::distributions::normal::StandardNormal;
use xorshift::{Rand,Rng,SeedableRng,SplitMix64,Xoroshiro128};
#[thread_local]
static mut RNG:Option<Xoroshiro128> = None;
pub fn seed(x:u64) {
let mut seeding_rng:SplitMix64 = SeedableRng::from_seed(x);
unsafe { RNG = Some(Rand::rand(&mut seeding_rng)); }
}
pub fn rnorm() -> f64 {
unsafe {
let StandardNormal(x) = RNG.as_mut().unwrap().gen::<StandardNormal>();
x
}
}
pub fn rnormv<R:DimName,C:DimName>() -> MatrixMN<f64,R,C>
where DefaultAllocator:Allocator<f64,R,C> {
unsafe { MatrixMN::<f64,R,C>::from_iterator(RNG.as_mut().unwrap().gen_iter().map(|x| { let StandardNormal(y) = x; y })) }
}