下面这段代码在长时间运行后,有一定的机率会出错,RandString(32)返回的全是 0.从网上查的资料全局变量应该不会被回收才对。
package helper
import (
"math/rand"
"time"
)
const _charsetRand = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$"
var _seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))
// RandStringWithCharset rand string with charset
func RandStringWithCharset(length int, charset string) string {
b := make([]byte, length)
l := len(charset)
for i := range b {
b[i] = charset[_seededRand.Intn(l)]
}
return string(b)
}
// RandString rand string
func RandString(length int) string {
return RandStringWithCharset(length, _charsetRand)
}
// RandInt rand int between [min, max)
func RandInt(min int, max int) int {
if min <= 0 || max <= 0 {
return 0
}
if min >= max {
return max
}
return _seededRand.Intn(max-min) + min
}
// RandMax rand int between [0, max)
func RandMax(max int) int {
if max <= 1 {
return 0
}
return _seededRand.Intn(max)
}
大家帮忙看一下,这是哪里出现问题了?
在第一段代码中,_seededRand 被多个 goroutine 同时访问和修改,因为没有对其进行同步操作或者使用互斥锁。而在第二段代码中,通过在 RandStringWithCharset 函数中调用 createRand 函数,每次都创建一个新的 _seededRand 实例,避免了并发访问全局变量的问题。通过这样的修改,确保了在并发情况下每个 goroutine 都有自己的 _seededRand 实例,从而解决了竞争条件问题,确保了程序的稳定性。