内容简介:一句话总结:math/rand 包中默认的随机数相关函数共享了一个全局锁, 即:所有使用默认随机函数的代码都会去竞争一个全局锁,有时这可能不是你想要的结果。
一句话总结:math/rand 包中默认的随机数相关函数共享了一个全局锁, 即:所有使用默认随机函数的代码都会去竞争一个全局锁,有时这可能不是你想要的结果。
比如 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
}
通过同样的方法查看其他默认的随机函数可以发现,所有的默认随机函数都共享了一个全局锁,调用这些默认随机函数的时候都会先进行一次获取锁的操作。
大部分情况下不需要管这个全局锁的问题,因为大部分情况下都不会介意这点性能消耗。 如果确实特别在意这点性能消耗的话,可以通过定义一个你的包共享的或者结构体实例共享的 Rand 实例来优化锁的性能消耗(最小化锁的粒度,不跟其他包/代码竞争这个锁)。
例子:
type Xyz struct {
// Rand 实例不是并发安全的,需要自行解决并发安全问题
rndMu sync.Mutex
rnd *rand.Rand
}
func (x *Xyz) random() int32 {
x.rndMu.Lock()
n := x.rnd.Int31()
x.rndMu.Unlock()
return n
}
func main() {
x := &Xyz{
rnd: rand.New(rand.NewSource(time.Now().UnixNano())),
}
fmt.Println(x.random())
}
或者可以考虑使用性能更好的第三方 rand 包: valyala/fastrand
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Python中init方法和随机数函数的使用
- Go语言学习笔记04--特殊函数&工程化结构&数组&随机数
- 区块链随机数的实现:墨客随机数子链RandDrop(强随机数和真随机数)_作者陈小虎
- Java随机数探秘
- Java 随机数探秘
- php里的随机数
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入浅出Node.js
朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00
本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码......一起来看看 《深入浅出Node.js》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
XML 在线格式化
在线 XML 格式化压缩工具