# Is \`rand()\` threadsafe?

**URL:** <https://discourse.julialang.org/t/is-rand-threadsafe/4683>\
**Category:** General Usage\
**Tags:** question, multithreading\
**Created:** [July 6, 2017, 9:02am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683 "2017-07-06T09:02:16Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)\
**Post date:** [July 6, 2017, 9:02am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/1 "2017-07-06T09:02:16Z")

</div>

While it seems to work and the output looks sensible, I have this lingering suspicion that `rand()` is not threadsafe and that using it in a `Thread.@threads` loop is volatile.

Browsing through `base/random.jl` and `base/dSFMT.jl` I saw no obvious sign of thread protection, which makes me wonder why it seems to work so well in the first place. Is `dSFMT` itself threadsafe maybe? I did not find any info on that.

So my question is if it is safe to call `rand()` in a `Threads.@threads` loop, and if not what the encourage way of doing so is.

Something like this?

```julia
julia> const trand_mutex = Threads.Mutex()
Base.Threads.Mutex(0, Ptr{Void} @0x00007ff8949c3fc0)

julia> function trand(args...)
           lock(trand_mutex)
           result = rand(args...)
           unlock(trand_mutex)
           result
       end
trand (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 6, 2017, 9:28am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/2 "2017-07-06T09:28:51Z")

</div>

> Is `rand()` threadsafe?

No. It won’t crash since there’s nothing really for it to crash, but it’ll not return the correct result and perform poorly.

> [@Evizero](#):
>
> if not what the encourage way of doing so is.

Create a rng per thread. What I’ve been doing is [here](https://github.com/nacs-lab/yyc-data/blob/8c7427334869f4c292eae9c8c3828ca03ec0244a/lib/NaCsCalc/src/utils.jl#L120-L142)

> [@Evizero](#):
>
> Something like this?

Definitely not.

---

<div class="post-metadata">

**Author:** ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)\
**Post date:** [July 6, 2017, 9:43am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/3 "2017-07-06T09:43:45Z")

</div>

Thanks for the quick reply!

> [@yuyichao](#):
>
> Create a rng per thread.

I know very little about random number generators, but I was under the impression that it is generally discouraged to use multiple RNG in parallel.

 ![](https://global.discourse-cdn.com/julialang/original/3X/7/2/72770c91ffb68a49fcd84a40416bed328ad3ba3b.png)

from [A Primer on Repeatable Random Numbers | Unity Blog](https://blogs.unity3d.com/2015/01/07/a-primer-on-repeatable-random-numbers/)

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 6, 2017, 9:56am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/4 "2017-07-06T09:56:17Z")

</div>

> [@Evizero](#):
>
> I was under the impression that it is generally discouraged to use multiple RNG in parallel.

No it just say that you need to be careful about initializing it. For my use case, I don’t care.

---

<div class="post-metadata">

**Author:** ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)\
**Post date:** [July 6, 2017, 10:00am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/5 "2017-07-06T10:00:39Z")

</div>

Understood, thanks for the help and example!

---

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [July 6, 2017, 3:50pm UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/6 "2017-07-06T15:50:20Z")

</div>

Won’t this make every thread have identical random numbers?

```julia
@noinline function init_thread_rng()
    # Allocate the random number generator on the thread's own heap lazily
    # instead of the master thread heap to minimize memory conflict.
    ThreadRNG[Threads.threadid()] = MersenneTwister(0)
end

```

I assume for separate random numbers per thread, it’d be fine to initialize with `MersenneTwister(Threads.threadid())`?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 6, 2017, 3:57pm UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/7 "2017-07-06T15:57:55Z")

</div>

> [@evanfields](#):
>
> have identical random numbers

Yes.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [July 8, 2017, 2:42am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/8 "2017-07-08T02:42:14Z")

</div>

My understanding of seeding is that method (of using consecutive small integers) isn’t necessarily any random than `MersenneTwister(0)`, but that you can jump one RNG ahead to effectively split it into two (or N) independent streams ([https://github.com/JuliaLang/julia/pull/12498](https://github.com/JuliaLang/julia/pull/12498)). I could be wrong though.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 10, 2017, 10:41am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/9 "2017-07-10T10:41:51Z")

</div>

Hi all

random.jl has a test which shows the usage of randjump  
[https://github.com/JuliaLang/julia/blob/c1f107fa99939ede9f963fef4044097215c77977/test/random.jl#L468](https://github.com/JuliaLang/julia/blob/c1f107fa99939ede9f963fef4044097215c77977/test/random.jl#L468)

I understand that the default jump in julia is 10^20.  
So if I need 36 random generators for 36 processes and on each thread I anticipate to generate around 10^13 random numbers. Am I safe by using the code below?  
Will each MersennTwister be 10^20 ‘apart’ from the next one? (the documentation is not too easy to read)?

```julia
seed=2001
mta = MersenneTwister(seed)
mts = randjump(mta, 36)
# -> use mts[x] on process x (for x in 1:36), rand(mts[x]) respectively 

```

If anyone could provide a jump polynomial for higher steps that would be nice. I was not able to use the code from the site below (as my C skills are nil)  
[http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/JUMP/dsfmt-jump.html](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/JUMP/dsfmt-jump.html)

Thank you

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [July 10, 2017, 10:52am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/10 "2017-07-10T10:52:40Z")

</div>

> Am I safe by using the code below?

yes

> Will each MersennTwister be 10^20 ‘apart’ from the next one?

yes

> If anyone could provide a jump polynomial for higher steps that would be nice

You can use the code at [MersenneTwister: implement generation of jump-ahead polynomials by rfourquet · Pull Request #16906 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/16906) (which bascically is a port from the C code you mention) and why not give support to this PR to help get it merged!

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 10, 2017, 11:15am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/11 "2017-07-10T11:15:22Z")

</div>

Thanks for the quick answer.

I now realize that I may run into issues when generating that man parallel ‘parts’ of a single mersenneTwister (considering its period of 10^61)

However it seems that there is apackage which solves my issues and has ‘better’ rngs:

[http://sunoru.github.io/RandomNumbers.jl/latest/](http://sunoru.github.io/RandomNumbers.jl/latest/)

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [July 10, 2017, 11:39am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/12 "2017-07-10T11:39:03Z")

</div>

> [@bernhard](#):
>
> considering its period of 10^61

Are you sure?  
Not 2^19937?

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 10, 2017, 12:30pm UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/13 "2017-07-10T12:30:53Z")

</div>

Oh. My bad.  
This is embarrassing, I must have confused 10^6001 (which should be close to 2^19937) with 10^61.

I guess this can only happen to someone with no intuition for power series.  
You are correct.  
Seems like I have plenty of ‘room’ available with 36\*20=720 \<\< 6001

That is to say: It is my understanding that the second element of the array would effectively start at the ‘random element’ 1+10^20 which the first MersenneTwister of the array produces.

---

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [September 4, 2019, 12:02am UTC](https://discourse.julialang.org/t/is-rand-threadsafe/4683/14 "2019-09-04T00:02:42Z")

</div>

Just in case anyone stumbles on this old thread, `rand()` and friends are now thread-safe (as of v1.3). See [here](https://julialang.org/blog/2019/07/multithreading) for more info.
