Go: 谨慎使用 math/rand 包中的默认随机数函数
2015 年 2 月 13 日
比如 rand.Int63
这个函数的 源代码
如下:
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
可以看到它其实是调用了一个全局的 Rand 实例 globalRand
,我们来看一下 globalRand
的 定义
:
var globalRand = New(&lockedSource{src: NewSource(1).(Source64)})
通过 New
的源码以及 globalRand.Int63n
的源码可以看到关键点是 lockedSource.Int63
方法的定义:
type lockedSource struct { lk sync.Mutex src Source64 } func (r *lockedSource) Int63() (n int64) { r.lk.Lock() n = r.src.Int63() r.lk.Unlock() return }
通过同样的方法查看其他默认的随机函数可以发现,所有的默认随机函数都共享了一个全局锁,调用这些默认随机函数的时候都会先进行一次获取锁的操作。