golang 文档说
与 Rand.Seed 方法不同,Seed 可以安全地并发使用。
该rand.Seed从实际上是math/rand包,但什么是种子?如果Seed是另一个函数,那么它不存在,math/rand所以不清楚该函数来自哪里?
更新:
我正在探索main我们执行的演示程序
rand.Seed(time.Now().UnixNano())
go process(...)
go process(...)
Run Code Online (Sandbox Code Playgroud)
其中process确定像
func process(...) {
time.Sleep(time.Duration(rand.Intn(30)) * time.Second)
...
}
Run Code Online (Sandbox Code Playgroud)
我们在两个不同的线程中使用相同的种子,那么这样的使用是否rand.Seed被认为是线程不安全的?
有一个功能,就有一个方法。您的报价来自于rand.Seed() Rand.Seed() Rand.Seed()方法。
math/rand包的全局函数在全局rand.Rand实例上运行。如果您检查以下源代码rand.Seed():
func Seed(seed int64) { globalRand.Seed(seed) }
Run Code Online (Sandbox Code Playgroud)
全局函数对于并发使用是安全的,因此所有其他包都可以使用它(以共享方式)。全球rand.Rand提供实例是为了方便起见,您可以“开箱即用”使用它,无需任何准备(除非需要对其进行正确播种)且无需任何同步。
的实例rand.Rand并发使用是不安全的,每个需要rand.Rand确定性随机序列的goroutine都应该创建一个,并适当地播种。或者如果 arand.Rand要在多个 goroutine 之间共享,则需要显式同步。
使用全局的优点 rand.Rand(通过全局函数)的是:(1)易于使用(与所有人隐式共享)和(2)不需要同步。
创建和使用自定义rand.Rand实例的优点:(1)它更快(它不是隐式同步)和(2)你可以控制谁可以访问它,所以你可以用它来重复伪随机序列(你可以不要对全局实例执行此操作,因为“任何人”都可以与您同时使用它)。
编辑:
我们在两个不同的线程中使用相同的种子,那么这样的使用是否
rand.Seed被认为是线程不安全的?
你只调用rand.Seed一次,所以实际上它是否线程安全都没有关系,它不是并发调用的。如果rand.Seed()同时从多个 goroutine 中调用,那么并发使用是否安全才重要。正如我在前面的回答中所述:“全局函数对于并发使用是安全的......”
您同时从多个 goroutine 调用的是rand.Intn(),但同样,这样做是安全的。