![](/img/trans.png)
[英]Is the UTC() call redundant in rand.Seed(time.Now().UTC().UnixNano())?
[英]A difference between Seed and Rand.Seed
golang文档说
与Rand.Seed方法不同,Seed可以安全地同时使用。
rand.Seed
实际上是来自math/rand
包,但什么是Seed? 如果Seed
是另一个函数,那么它在math/rand
不存在,所以不清楚该函数的来源是什么?
更新:我正在探索我们执行main
的演示程序
rand.Seed(time.Now().UnixNano())
go process(...)
go process(...)
确定process
地方就像
func process(...) {
time.Sleep(time.Duration(rand.Intn(30)) * time.Second)
...
}
我们在两个不同的线程中使用相同的种子,所以使用rand.Seed
被认为是一个不安全的线程?
有一个rand.Seed()
函数 ,还有一个Rand.Seed()
方法 。 您的引用源自Rand.Seed()
方法的文档。
math/rand
包的全局函数在全局rand.Rand
实例上运行。 如果你检查rand.Seed()
的源代码:
func Seed(seed int64) { globalRand.Seed(seed) }
全局函数对于并发使用是安全的,因此所有其他包都可以使用它(以共享方式)。 提供全局rand.Rand
实例是为了方便,您可以“开箱即用”而无需任何准备(除了需要正确播种它)并且没有任何同步。
rand.Rand
实例对于并发使用是不安全的,每个需要rand.Rand
goroutine.Rand对于确定性随机序列应该创建一个,并适当地播种它。 或者如果要在多个goroutine之间共享rand.Rand
,则需要显式同步。
使用全局rand.Rand
(通过全局函数)的优点是:(1)易用性(它与每个人隐式共享)和(2)不需要同步。
创建和使用自定义rand.Rand
实例的优点:(1)它更快(它没有隐式同步)和(2)你控制谁有权访问它,所以你可以用它来重复伪随机序列(你不能用全局实例做到这一点,因为“任何人”可能会与你同时使用它)。
编辑:
我们在两个不同的线程中使用相同的种子,所以使用
rand.Seed
被认为是一个不安全的线程?
你只调用rand.Seed
一次,所以实际上它甚至不管它是否是线程安全的,它不是同时调用的。 如果同时从多个goroutine调用rand.Seed()
,那么它是否对于并发使用是安全的。 正如我在前面的回答中所说: “全球功能对于并发使用是安全的......”
您同时从多个goroutine调用的是rand.Intn()
,但同样,这样做是安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.