繁体   English   中英

Seed和Rand.Seed之间的区别

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM