如何创建线程安全的rand.Source?

问题描述 投票:0回答:2

标准库 rand.NewSource 函数的

文档
指出,

与顶级函数使用的默认 Source 不同,此源是 多个 goroutine 并发使用不安全。

有没有办法创建线程安全的

rand.Source

上下文:我有一个类型,其方法可能被多个 go 例程调用,并且该方法使用随机数。我想支持依赖注入进行测试,所以不能使用默认的Source。

go random dependency-injection
2个回答
8
投票

通常使用 sync.Mutex 来确保不会同时访问一个或多个值。以下是如何使用sync.Mutex来保护rand。来源:

 var s = rand.NewSource(seed)
 var mu sync.Mutex

// lock/unlock when accessing source from a goroutine
mu.Lock()
i := s.Int63()
mu.Unlock()
 

rand.Rand不支持并发使用。如果应用程序使用 rand.Source 创建 rand.Rand,则改为保护 rand.Rand:

 var r = rand.New(rand.NewSource(seed))
 var mu sync.Mutex

// lock/unlock when accessing the rand from a goroutine
mu.Lock()
i := r.Int()
mu.Unlock()

用于保护 rand 的互斥量。Rand 也会保护 rand.Source。


2
投票

经过一番调查,我了解到解决方法是使用互斥锁来保护源。标准库甚至包含一个实现

lockedSource
,但相关类型未导出

© www.soinside.com 2019 - 2024. All rights reserved.