gpt4 book ai didi

go - Seed 和 Rand.Seed 的区别

转载 作者:IT王子 更新时间:2023-10-29 01:56:33 33 4
gpt4 key购买 nike

golang 文档说

Seed, unlike the Rand.Seed method, is safe for concurrent use.

rand.Seed 实际上是来自math/rand 包,但是Seed 是什么?如果 Seed 是另一个函数,那么它不存在于 math/rand 中,因此不清楚该函数从何而来?

更新:我正在探索演示程序,我们在 main 中执行

rand.Seed(time.Now().UnixNano())
go process(...)
go 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.Rand 要在多个 goroutine 之间共享,则需要显式同步。

使用全局 rand.Rand(通过全局函数)的优点是:(1) 易于使用(它与所有人隐式共享)和 (2) 不需要同步。

创建和使用自定义 rand.Rand 实例的优点:(1) 它更快(它不是隐式同步的)和 (2) 您可以控制谁可以访问它,因此您可以使用它来重复伪随机序列(您不能对全局实例执行此操作,因为“任何人”都可能与您同时使用它)。

编辑:

We are using the same seed in two different threads, so is such using of rand.Seed considered to be a thread non-safe?

你只调用了一次rand.Seed,所以实际上线程安全与否并不重要,它不会被并发调用。如果 rand.Seed() 会同时从多个 goroutines 调用,那么它是否安全并发使用才重要。正如我之前在回答中所述:“全局函数对于并发使用是安全的……”

您同时从多个 goroutine 调用的是 rand.Intn(),但同样,这样做是安全的。

关于go - Seed 和 Rand.Seed 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53990816/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com