Description
I apologize if this is a duplicate issue. I looked and couldn't quite find this one...
According to math/rand
package documentation, the following is not concurrency safe:
var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))
NewSource returns a new pseudo-random Source seeded with the given value. Unlike the default Source used by top-level functions, this source is not safe for concurrent use by multiple goroutines.
The aforementioned "default source," is (rightfully) not exported by the math/rand
package. So the only way to generate random numbers in a concurrency-safe fashion (with this package, at least) is to resort to using package level functions that rely on the default, concurrency-safe source.
To seed that, one must make a call similar to the following:
rand.Seed(time.Now().UnixNano())
But this is equally a problem! Why? Because nothing prevents any other bit of code from also seeding/re-seeding the math/rand
package-level default source. Consider the possibility that some third party package that is initialized after one has seeded the source re-seeds the source with a constant-- bye, bye, psuedo-randomness; hello determinism.
The bottom line here is that achieving concurrency safety with math/rand
forces one down a path that's dependent on package-level globals and that introduces its own problems. It's out of the frying pan and into the fryer, and that is (for me at least) making the package nearly unusable.