内容简介:一句话总结: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里的随机数
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入浅出Web设计(中文版)
(美)瓦特罗尔、(美)西罗托 / O'Reilly Taiwan公司 / 东南大学出版社 / 2010-11 / 99.00元
你将从《深入浅出Web设计(中文版)》学到什么?你曾经希望看看书就能学到真正的网站设计吗?曾经想过该如何同时达成让网站看起来美观,又能有效率地沟通信息,还要通过可访问性与可用性的策略吗?《深入浅出Web设计》正是精通上述主题的秘笈。我们将学到如何设计一个绝佳、用户友好的网站,上谈客户需求,下说手绘分镜表,乃至完成在线所需的HTML与css主文件……而且会有一个真正可以运作的网站!一起来看看 《深入浅出Web设计(中文版)》 这本书的介绍吧!